2.2 示例:使用K-近邻算法改进约会网站的配结果

  1. 收集数据:提供文本文件
  2. 准备数据:使用Python解析文本文件(文本转numpy矩阵、归一化数据等)
  3. 分析数据:使用Matplotlib画二维扩散图
  4. 训练算法:此步骤不适用于k-紧邻算法
  5. 测试算法:使用海伦提供的部分数据作为测试样本。测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误
  6. 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型

1、数据:机器学习实战源码及数据集

密码:6irz

2、准备数据

# 将文本转换成Numpy矩阵
def fileToMatrix(filename):# 打开文件fr = open(filename)arrayOfLines = fr.readlines()numberOfLines = len(arrayOfLines)# 构建一个全零矩阵用来存储特征信息returnMat = zeros((numberOfLines, 3))# 构建一个标签数组用来存储特征对应的类别标签classLabelVector = []index = 0for line in arrayOfLines:line = line.strip()listFromLine = line.split('\t')# 复制特征信息returnMat[index, :] = listFromLine[0:3]# 复制类别标签classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector# 归一化数据
def autoNorm(dataSet):# min(0)每一列中的最小值, min(1)每一行中的最小值minValues = dataSet.min(0)# max(0)每一列中的最大值maxValues = dataSet.max(0)# 取值范围ranges = maxValues - minValues# 初始化矩阵normDataSet = mat(zeros(shape(dataSet)))# print(normDataSet)# 返回dataset的行数m = dataSet.shape[0]normDataSet = dataSet - tile(minValues, (m, 1))normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minValues

3、分析数据

  • 这里用到了上一部分的fileToMatrix函数进行数据转换
  • matplotlib包
import matplotlib.pyplot as plt
from chapter2.KNN import *datingDataMat, datingLabels = fileToMatrix("datingTestSet2.txt")fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:, 0], datingDataMat[:, 1], 15.0*array(datingLabels), 15.0*array(datingLabels))
plt.show()

可以自行设置横纵坐标轴表示的数据,即scatter()的前两个参数,如下

5、测试算法

# !/usr/bin/env python
# -*- coding: utf-8 -*-from chapter2.KNN import *# 分类器针对约会网站分类
def datingClass():hoRatio = 0.10datingDataMat, datingLabels = fileToMatrix("datingTestSet2.txt")normMat, ranges, minValues = autoNorm(datingDataMat)m = normMat.shape[0]numTestVecs = int(m * hoRatio)errorCount = 0.0for i in range(numTestVecs):classifierResult = classfiy0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]))if(classifierResult != datingLabels[i]):errorCount += 1.0print("the total error rate is : %f" % (errorCount / float(numTestVecs)))datingClass()

另外附上完整的KNN.py文件(Python3)

from numpy import *
import operator# 构造分类器,用于分类的inX, 训练的样本集dataSet, 标签向量labels, 最近邻居数目k
def classfiy0(inX, dataSet, labels, k):# shape[0]返回行数, shape[1]返回列数dataSetSize = dataSet.shape[0]"""1、把当前数据复制成训练集大小,以便同训练集中每一个数据比较"""# tile(A, n)将A数组重复n次, 这里是列数不变,行数变dataSetSize行# 跟dataset做差,即与每一个训练数据做差(求距离)diffMat = tile(inX, (dataSetSize, 1)) - dataSet# 分别对每一个数据平方sqdiffMat = diffMat**2# 将矩阵的每一行向量相加sqDistance = sqdiffMat.sum(axis=1)# 平方根distances = sqDistance**0.5"""2、将比较结果排序"""# 返回从小到大排序后的索引值sortedDistIndicies = distances.argsort()"""3、统计最近k个值的类别"""# 新建字典,保存最近的K个值分别是什么类别classCount = {}for i in range(k):# 获取第i个值的类别voteIlabel = labels[sortedDistIndicies[i]]# 统计每个得数目classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1"""4、对统计结果拍序"""sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)"""5、返回在这K个值中,出现次数最多的类别"""return sortedClassCount[0][0]# 将文本转换成Numpy矩阵
def fileToMatrix(filename):# 打开文件fr = open(filename)arrayOfLines = fr.readlines()numberOfLines = len(arrayOfLines)# 构建一个全零矩阵用来存储特征信息returnMat = zeros((numberOfLines, 3))# 构建一个标签数组用来存储特征对应的类别标签classLabelVector = []index = 0for line in arrayOfLines:line = line.strip()listFromLine = line.split('\t')# 复制特征信息returnMat[index, :] = listFromLine[0:3]# 复制类别标签classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector# 归一化数据
def autoNorm(dataSet):# min(0)每一列中的最小值, min(1)每一行中的最小值minValues = dataSet.min(0)# max(0)每一列中的最大值maxValues = dataSet.max(0)# 取值范围ranges = maxValues - minValues# 初始化矩阵normDataSet = mat(zeros(shape(dataSet)))# print(normDataSet)# 返回dataset的行数m = dataSet.shape[0]normDataSet = dataSet - tile(minValues, (m, 1))normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minValues

6、使用算法:输入特征数据以判断对方是否是自己喜欢的类型

# !/usr/bin/env python
# -*- coding: utf-8 -*-from chapter2.KNN import *def classifyPerson():resultList = ['not at all', 'in small doses', 'in large doses']percentTats = float(input("percentage of time spent playing video games?"))ffMiles = float(input("frequent flier miles earned per year?"))iceCream = float(input("liters of ice cream consumed per year?"))datingMat, datingLabels = fileToMatrix("datingTestSet2.txt")normMat, ranges, minValues = autoNorm(datingMat)inArry = [ffMiles, percentTats, iceCream]classifierResult = classfiy0(inArry, datingMat, datingLabels, 3)print("You will probably like this person: " + resultList[classifierResult - 1])classifyPerson()

2.3 示例:手写识别系统

1、收集数据:见上

2、准备数据:编写imgToVector(), 将图像格式转换为分类器使用的向量格式

# 将二进制图像矩阵转换成一维数组
def imgToVector(filename):returnVect = zeros((1, 1024))# 打开文件fr = open(filename)for i in range(32):linestr = fr.readline()for j in range(32):returnVect[0, 32*i+j] = int(linestr[j])return returnVect

3、测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。

# !/usr/bin/env python
# -*- coding: utf-8 -*-
from os import listdirfrom chapter2.KNN import *# 将二进制图像矩阵转换成一维数组
def imgToVector(filename):returnVect = zeros((1, 1024))# 打开文件fr = open(filename)for i in range(32):linestr = fr.readline()for j in range(32):returnVect[0, 32*i+j] = int(linestr[j])return returnVect# 手写数字识别
def handwritingClassTest():hwLabels = []# 训练数据集trainingFileList = listdir('trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 获取文件名fileNameStr = trainingFileList[i]filestr = fileNameStr.split('.')[0]classNumStr = int(filestr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = imgToVector("trainingDigits/%s" % fileNameStr)# 测试数据集testFileList = listdir("testDigits")errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]filestr = fileNameStr.split('.')[0]classNumStr = int(filestr.split('_')[0])vectorUnderTest = imgToVector("trainingDigits/%s" % fileNameStr)classifierResult = classfiy0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with: %d, the real answer is : %d" % (classifierResult, classNumStr))if classifierResult != classNumStr:errorCount += 1.0print("the total number of errors is : %d" % errorCount)print("the total error rate is : %f" % (errorCount / float(mTest)))handwritingClassTest()

个人问题及总结:

  • 自己的测试结果与树上的测试结果不一样,有细微差距,不知道具体是什么原因
  • KNN文件中归一化数据时(autoNorm(dataSet))中在进行初始化矩阵时,Pycharm总提示变量未被使用,感觉是normDataSet指向了一个全零矩阵,然后normDataSet又指向了dataSet - tile(minValues, (m, 1)),初始化全零矩阵完全没有起到作用,感觉这可能是测试结果不一样的原因吧,希望了解的兄弟能告知一下该怎么处理

《机器学习实战》chapter02 K-近邻算法(KNN)相关推荐

  1. 机器学习-分类之K近邻算法(KNN)原理及实战

    k近邻算法(KNN) 简介 KNN算法是数据挖掘分类技术中最简单的方法之一.它通过测量不同特征值之间的距离进行分类的.其基本思路为:如果一个样本在特征空间中的k个最近邻样本中的大多数属于某一个类别,则 ...

  2. 机器学习实战之K近邻算法

    k近邻算法概述 简单地说,K近邻算法采用测量不同特征值之间的距离方法进行分类. 优 点 :精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. ...

  3. 【机器学习实战】k近邻算法实战——手写识别系统

    文章目录 手写识别系统 步骤: 准备数据:将图像转换为测试向量 测试算法:使用k-近邻算法识别手写数字 [完整代码] 手写识别系统 为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6.需要识 ...

  4. 01 K近邻算法 KNN

    01 K近邻算法 KNN k近邻算法基础 等价于 scikit-learn中的机器学习算法封装 训练数据集,测试数据集 分类准确度 超参数 考虑距离权重 更多关于距离的定义 搜索明可夫斯基距离相应的p ...

  5. 基于KD树的K近邻算法(KNN)算法

    文章目录 KNN 简介 KNN 三要素 距离度量 k值的选择 分类决策规则 KNN 实现 1,构造kd树 2,搜索最近邻 3,预测 用kd树完成最近邻搜索 K近邻算法(KNN)算法,是一种基本的分类与 ...

  6. k近邻算法(KNN)-分类算法

    k近邻算法(KNN)-分类算法 1 概念 定义:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. k-近邻算法采用测量不同特征值之间的 ...

  7. k近邻算法 (KNN)

    k近邻算法 k近邻算法(KNN,K-NearestNeighbor)是一种基本分类和回归方法,监督学习算法,本质上是基于一种数据统计的方法: 核心思想:给定一个训练数据集,对新的输入实例,在训练数据集 ...

  8. 【白话机器学习】算法理论+实战之K近邻算法

    作者1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻 ...

  9. k近邻算法_【白话机器学习】算法理论+实战之K近邻算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...

  10. 白话机器学习算法理论+实战之K近邻算法

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,比如我之前写过的一篇十大机器学习算法的小总结,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑 ...

最新文章

  1. 第三章:创建用户界面组件--可视化组件(一)
  2. 产品上线前会发生什么故事? | 每日趣闻
  3. python导包顺序_2019-03-21 python导入包以及Python程序执行顺序理解
  4. python绘制动态模拟图-如何利用Python动态模拟太阳系运转
  5. PHP安装TP6的composer install报Undefined index: process 进程依赖于proc_open 这个函数不可用
  6. 他95年出生,却拥有10年编程经验
  7. 期货黄金与现货黄金比较
  8. . NET5实战千万高并发项目,性能吊打JAVA,C#排名万年老五,有望逆袭!
  9. Chrome DevTools的Network面板
  10. linux chattr修改文件属性,linux chattr(改变文件属性)
  11. 王学丹 确定测试原始需求
  12. NYOJ266 - 字符串逆序输出
  13. Python爬虫之酷安应用商店
  14. 计算机绘图CAD实训指导,【精品】CAD计算机绘图实习指导书
  15. python模拟登录163邮箱_python模拟登陆163邮箱并获取通讯录 | 学步园
  16. 一周技术学习笔记(第58期)-如何突破第四章障碍
  17. android中实现图片圆形效果
  18. Windows XP IIS 500错误
  19. 设计一个抽象类图形类,在该类中包含有至少两个抽象方法求周长和求面积,分别定义圆形类、长方形类、正方形类来继承图形类,并实现上述两个方法。并创建实例验证。
  20. 山姆公司关于营销培训方案

热门文章

  1. 吴恩达的 AI 战略强调了什么?
  2. AliSQL 20170716版本发布 Invisible Indexes 功能和 SELECT FROM UPDATE 语法
  3. 想要做服务类APP,先来看看独立商城系统开发方案
  4. 【Other】Ubuntu 14.04 pptp 客户端连接配置
  5. .NET Socket服务编程之-高效连接接入编
  6. WordPress在nginx下的URL重写规则
  7. CodeIgniter笔记4
  8. 【转贴】Decoda Tutorial LUA调式器
  9. 领英上面的experience和project的区别
  10. LINUX下文件字符集编码查看与转换并文件名编码转换