人生苦短,我用Python

K-近邻算法:简单来说,K-近邻算法就是采用测量不同特征值之间的距离方法进行分类

  • 优点:精度高、对异常值不敏感、无数据输入假定
  • 缺点:计算复杂度高、空间复杂度高
  • 适用范围:数值型、标称型

工作原理:

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似的数据(最近邻)的分类标签。一般来说,我们只选择样本集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。最后,选择K个最相似数据中出现次数最多的分类,作为新数据的分类。

K-近邻算法的一般流程:

  1. 收集数据:可以使用任何方法。
  2. 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
  3. 分析数据:可以使用任何方法。
  4. 训练算法:此步骤不适用于K-近邻算法。
  5. 测试算法:计算错误率。
  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行K-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理。

实施KNN分类算法--伪代码

对未知类别属性的数据集中的每个点依次执行以下操作:

  1. 计算已知类别数据集中的点与当前点之间的距离;
  2. 按照距离递增次序排序;
  3. 选取与当前点距离最小的K个点;
  4. 确定前K个点所在类别的出现频率;
  5. 返回前K个点出现频率最高的类别作为当前点的预测分类;

计算两个向量点之间的距离公式--欧式距离公式:

例如:点(0,0)与(1,2)之间的距离计算为:

sqrt((1-0)**2+(2-0)**2)

代码实现:

import numpy as np
import operator
"""
def CreateDataSet():group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])labels=['A','A','B','B']return group,labels
print(CreateDataSet())
"""
"""
inX--用于分类的输入向量
dataSet--输入的训练样本集
labels--标签向量
k--用于选择最近邻居的数目
其中标签向量的元素数目和矩阵dataSet的行数相同
"""
def classify(inX,dataSet,labels,k):dataSetSize=dataSet.shape[0]    #获得训练样本集的行数#将输入向量在列方向重复一次,在行方向上dataSize次,并与训练样本集dataSet相减diffMat=np.tile(inX,(dataSetSize,1))-dataSetprint("diffMat:")print(diffMat)#将相减后的集合进行平方运算sqDiffMat=diffMat**2print("sqDiffMat:")print(sqDiffMat)#对平方后的集合进行相加运算--按行相加sqDistances=sqDiffMat.sum(axis=1)print("sqDistances:")print(sqDistances)#对相加后的数据开平方,得到输入向量与每个训练样本集之间的距离值distances=np.sqrt(sqDistances)print("distances")print(distances)#返回数组从小到大的索引值--排序sortedDistIndicies=np.argsort(distances)print("sortedDistIndicies")print(sortedDistIndicies)classCount={}for i in range(k):voteIlabel=labels[sortedDistIndicies[i]]print("voteIlabel"+str(i))print(voteIlabel)classCount[voteIlabel]=classCount.get(voteIlabel,0)+1print("classCount"+str(i))print(classCount)sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)print("sortedClassCount:")print(sortedClassCount)return sortedClassCount[0][0]if __name__=='__main__':#训练样本集group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])#标签向量labels = ['A', 'A', 'B', 'B']#输入向量inX=[0,0]#用于选择最近邻居的数目k=3result=classify(inX,group,labels,k)print(result)"""
输出值:
diffMat:
[[-1.  -1.1][-1.  -1. ][ 0.   0. ][ 0.  -0.1]]
sqDiffMat:
[[ 1.    1.21][ 1.    1.  ][ 0.    0.  ][ 0.    0.01]]
sqDistances:
[ 2.21  2.    0.    0.01]
distances
[ 1.48660687  1.41421356  0.          0.1       ]
sortedDistIndicies
[2 3 1 0]
voteIlabel0
B
classCount0
{'B': 1}
voteIlabel1
B
classCount1
{'B': 2}
voteIlabel2
A
classCount2
{'B': 2, 'A': 1}
sortedClassCount:
[('B', 2), ('A', 1)]
BProcess finished with exit code 0
"""复制代码

测试结果:

输入[0,0],经过测试后,返回的结果是B,也就是说[0,0]这个输入向量通过K-近邻算法分类后归为B类

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

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

准备数据:从文本文件中解析数据

文本样本数据特征:

  • 每年获得的飞行常客里程数
  • 玩视频游戏所耗时间的百分比
  • 每周消费的冰淇淋公升数

将文本记录转换为numpy数据的解析程序:

def file2matrix(filename):# 打开文件fr = open(filename, 'r', encoding='utf-8')# 按行读取数据arrayOLines = fr.readlines()# 获取数据的行数numberOfLines = len(arrayOLines)# 创建以0填充的矩阵returnMat = np.zeros((numberOfLines, 3))print(returnMat)classLabelVector = []index = 0for line in arrayOLines:print(line)# 截取掉所有回车字符line = line.strip()print(line)# 以'\t'将line分割成一个元素列表listFromLine = line.split('\t')# 选取前三个元素,存储到特征矩阵中returnMat[index, :] = listFromLine[0:3]# 选取最后一个元素存储到标签向量中classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat, classLabelVector
datingDataMat,datingLabels=file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')
fig=plt.figure()
plt.title('K-')
plt.xlabel('fly')
plt.ylabel('consume')
ax=fig.add_subplot(111)ax.scatter(datingDataMat[:,0],datingDataMat[:,1],15.0*np.array(datingLabels),15.0*np.array(datingLabels))
plt.show()复制代码

特别说明:代码中的资源文件可以在此处下载:LiuGuoJiang/machinelearninginaction

解析文本数据并用散点图展示:


准备数据:归一化数值

任选样本数据中一行数据,计算距离时,因为飞行常客里程数比较大,所以对最后计算结果影响过大,所以需要对数据做归一化处理。如将取值范围处理为0~1或者-1~1之间。下面的公式可以将任意取值范围的特征值转化为0~1区间内的值:

newValue=(oldValue-min)/(max-min)

  • 其中min和max分别是数据集中的最小特征值和最大特征值。

归一化特征值函数:

def autoNorm(dataSet):#选取列的最小值minVals=dataSet.min(0)#选取列的最大值maxVals=dataSet.max(0)#列的最大值与最小值做减法ranges=maxVals-minVals#normDataSet=np.zeros([dataSet.shape[0],dataSet.shape[1]])print(normDataSet)#取出dataSet的行数m=dataSet.shape[0]#np.tile(minVals,(m,1))将minVals在 列上重复一次,在行上重复m次normDataSet=dataSet-np.tile(minVals,(m,1))  #(oldValue-min)normDataSet=normDataSet/np.tile(ranges,(m,1))   #(oldValue-min)/(max-min)return normDataSet,ranges,minValsnormDataSet,ranges,minVals=autoNorm(datingDataMat)
print(normDataSet)复制代码

测试算法:机器学习算法一个很重要的工作就是评估算法的正确率,通常我们只提供已有数据的90%作为训练样本来训练分类器,而使用其余的10%数据去测试分类器,检测分类器的正确率。10%数据应该是随机选择的。

分类器的测试代码:

def datingClassUnitTest():hoRatio=0.10datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')print(datingDataMat)normDataSet, ranges, minVals = autoNorm(datingDataMat)print(normDataSet)m=normDataSet.shape[0]numTestVecs=int(m*hoRatio)print("numTestVecs")print(numTestVecs)errorCount=0.0for i in range(numTestVecs):classifierResult=classify(normDataSet[i,:],normDataSet[numTestVecs:m,:],datingLabels[numTestVecs:m],3)print("the classfier came back with:{},the real answer is:{}".format(classifierResult,datingLabels[i]))if (classifierResult!=datingLabels[i]):errorCount+=1.0print("the total error rate is:{}".format(errorCount/float(numTestVecs)))the classfier came back with:3,the real answer is:3
the classfier came back with:2,the real answer is:2
the classfier came back with:1,the real answer is:1
.........
the classfier came back with:1,the real answer is:1
the classfier came back with:3,the real answer is:3
the classfier came back with:3,the real answer is:3
the classfier came back with:2,the real answer is:2
the classfier came back with:1,the real answer is:1
the classfier came back with:3,the real answer is:1
the total error rate is:0.05复制代码

分类器处理数据集的错误率是5%,即代表此分类器可以帮助对象判定分类。

编写可以让用户输入自己需要判断的输入向量,通过该分类器帮助用户判断属于哪一分类:

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?"))datingDataMat, datingLabels = file2matrix('D:\liuguojiang_Python\city_58\city_58\datingTestSet2.txt')normDataSet, ranges, minVals = autoNorm(datingDataMat)inArr = np.array([ffMiles, percentTats, iceCream, ])classifierResult = classify((inArr - \minVals) / ranges, normDataSet, datingLabels, 3)print("You will probably like this person: {}".format(resultList[classifierResult - 1]))
if __name__=='__main__':classifyPerson()"""
return:
percentage of time spent playing video games?10
frequent flier miles earned per year?10000
liters of ice cream consumed per year?0.5
You will probably like this person: in small doses
"""复制代码

总结:

  1. 定义K-近邻算法程序。
  2. 定义将文本数据集处理成二维数组的函数,便于处理。
  3. 为消除某一特征数值过大对结果判定的影响,定义归一化数值函数,公式:(oldValue-min)/(max-min)
  4. 定义测试算法函数,用于测试分类器的错误率是否满足使用要求。
  5. 定义可以让用户输入的代码,输入输入向量,用于判定分类

机器学习笔记1(K-近邻算法)相关推荐

  1. 01. 机器学习笔记01——K近邻算法 , CV_example

    K近邻算法(K-nearest neighbor,KNN算法) 李航博士<统计学习方法> 最近邻(k-Nearest Neighbors,KNN)算法是一种分类算法 应用场景:字符识别.文 ...

  2. 2、python机器学习基础教程——K近邻算法鸢尾花分类

    一.第一个K近邻算法应用:鸢尾花分类 import numpy as np from sklearn.datasets import load_iris from sklearn.model_sele ...

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

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

  4. 机器学习——聚类之k近邻算法及python使用

    聚类算法之k近邻及python使用 什么是k近邻算法 k近邻算法流程 使用sklearn进行代码实现 数据集介绍 标准化 代码实现 写在开头,套用我的老师的一句话目前所有自然学科的前沿都是在研究数学, ...

  5. 统计学习方法笔记(一)-k近邻算法原理及python实现

    k近邻法 k近邻算法 算法原理 距离度量 距离度量python实现 k近邻算法实现 案例地址 k近邻算法 kkk近邻法(kkk-NN)是一种基本分类和回归方法. 算法原理 输入:训练集 T={(x1, ...

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

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

  7. 笔记:K近邻算法理论与实现

    numpy实现版本: import numpy as np import operator# 准备数据集 X = np.array([[2,2],[1,1.5],[1,1],[4,3],[4,4]]) ...

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

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

  9. 【机器学习】机器学习从零到掌握之二 -- 教你实现K近邻算法

    本文是<机器学习从零到掌握>系列之第2篇 [机器学习]机器学习从零到掌握之一 -- 教你理解K近邻算法 伪代码如下: 对未知类别属性的数据集中的每个点一次执行以下操作: (1)计算已知类别 ...

  10. 【机器学习入门】(1) K近邻算法:原理、实例应用(红酒分类预测)附python完整代码及数据集

    各位同学好,今天我向大家介绍一下python机器学习中的K近邻算法.内容有:K近邻算法的原理解析:实战案例--红酒分类预测.红酒数据集.完整代码在文章最下面. 案例简介:有178个红酒样本,每一款红酒 ...

最新文章

  1. JQUERY打造隐藏在左侧的弹性弹出菜单
  2. xcode 的一些问题
  3. 关于拓扑排序的问题-P3116 [USACO15JAN]会议时间Meeting Time
  4. 如何使用Squid服务来构建=》传统和透明代理服务器,通俗易懂!
  5. 重新设计Hamcrest
  6. 在linux实现公平队列,多级反馈队列调度策略在Linux中的应用和实现.pdf
  7. C++: new是否进行初始化的问题
  8. 【Elasticsearch】es Timelion是Kibana中时间序列的可视化工具
  9. 安卓-内部存储、外部存储目录
  10. 安装PetShop后调试的诸多问题
  11. github java开源项目经验_GitHub 上最火的开源项目 —— Java 篇
  12. JavaScript事件委托的技术原理
  13. 【备忘】Python编程实践视频教程+教材 27集 下载
  14. 印刷体汉字识别matlab实现,如何用MATLAB仿真印刷体汉字识别系统?
  15. mac系统 彻底删除安全助手
  16. 少儿计算机兴趣小组活动记录,小学美术兴趣小组活动记录-(一).doc
  17. 阿里云1核1G内存1M宽带支持多少IP访问量够用吗?
  18. WEEK 15 B ZJM 与生日礼物
  19. centos ssh免密登录 多台互相免密登录
  20. AdvancedInstaller打包工具使用(五)

热门文章

  1. 强化学习——Qlearning
  2. python中的glob 模块学习文件路径查找
  3. python超神之路:python异常对照表
  4. H3C FTP配置示例
  5. Oracle Study之--Oracle 11gR2通过RMAN克隆数据库
  6. 2600: [Ioi2011]ricehubh
  7. 夜深人静,想规划一下短期
  8. 酒鬼随机漫步(一个矢量类)
  9. 结合file和iconv命令转换文件的字符编码类型
  10. 如何在webservice中取得sesssionid