【ML学习笔记】12:k-近邻算法的demo
来源:互联网 发布:win7系统数据恢复 编辑:程序博客网 时间:2024/06/18 07:12
k-近邻算法(KNN)是一种有监督学习的分类算法,属于非概率分类器。
其基本思路就是,实例的每一个特征都可以赋予一个值去度量,如果有n个特征,那么也就是相当于实例在n维空间中(n个方向各自不同,显然这种假定是建立在我们认为这些特征互不相关的基础上的)。
而k-近邻算法也就是,把这个投入到学习机器去做预测的实例的特征向量,认定是表达了n维空间上的一个点,这个空间不见得是欧式空间,然后去寻找训练集中k个和这个点距离最近(这个距离自然是定义在这个空间上的距离)的点对应的实例,去看这些实例对应的标签,出现频数最多的那个标签就成为我们kNN算法预测的标签。
下面这个demo是跟着书上做的,加了一些可视化的成分,有很多细节值得注意,算是回顾了python的小部分语法。
这是一个后缀名为.py的模块,写好以后,在命令行进入到这个模块文件所在的目录,然后再进入python回显界面去使用它!
#-*-coding:utf-8-*-from numpy import * #科学计算包import operator #运算符模块from matplotlib import pyplot as plt#上一行的末尾不能打注释!#创建训练集和标签def createDataSet(): #训练集的特征 group=array( [[1.0,1.1],[1.0,1.0],[0.1,0],[0,0.1], [0.9,1.0],[1.0,0.7],[0.2,0],[0.1,0.1], [1.1,1.0],[0.8,1.1],[0.1,0.4],[0.3,0.2]]) #对应的标签 labels=['A','A','B','B', 'A','A','B','B', 'A','A','B','B'] return group,labels#k-近邻算法(输入的特征向量,训练集特征向量矩阵,训练集标签向量,k值)def KJL(inX,dataSet,labels,k): #用shape[0]读取训练集第一维的长度(行数即训练集实例数) dataSetRow=dataSet.shape[0] #用shape[1]读取训练集第二维的长度(列数即特征数) dataSetCol=dataSet.shape[1] #读取输入向量的列数(特征数) inXCol=len(inX) #训练集标签向量的个数 labelsLen=len(labels) #对训练集的判定 if labelsLen!=dataSetRow: print "训练集的特征集和标签集实例数目不等" return #对输入的判定 if inXCol!=dataSetCol: print "用于测试的的实例的特征数目和训练集特征数目不等" return #用tile()将输入的特征向量重复成和训练集特征向量一样多的行 #变成2维,里面的维度重复1次,外面一层重复dataSetRow次 diffMat=tile(inX,(dataSetRow,1)) #减去训练集特征向量矩阵得到存偏差的矩阵 diffMat=diffMat-dataSet #将减出来的偏差矩阵每个元素平方 sqDiffMat=diffMat**2 #对行求和,表示这个实例和这行对应的训练集实例的L2范数的平方 sqDistances=sqDiffMat.sum(axis=1) #为了方便就不开根号(**0.5)了 #argsort()返回其从小到大排序的排序索引序列 sortIndex=sqDistances.argsort() #空字典,用来存各个标签在前k邻居中出现的次数 classCount={} #找前k个距离最近的,也就是排序下标从0~k-1的 for i in range(k): #暂存第i近(从0计数)训练集实例的标签 voteIlab=labels[sortIndex[i]] #先取字典中以这个标签为key的value值,如果没有则返回0 #加上1作为以这个标签为key的value值 classCount[voteIlab]=classCount.get(voteIlab,0)+1 #把classCount用iteritems()方法变成可迭代对象传入 #用operator.itemgetter()方法定义一个函数给参数key,这个函数按1号域排序 #将reverse参数显示修正为True,表示降序排序(找频数最大的) sortedClassCount=sorted( classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #排序好后,第0个对象就是要找的那个频率最高的实例的[标签,频率]了 #只返回标签 return sortedClassCount[0][0]#显示训练集和输入的实例(二维特征)#(输入的特征向量,训练集特征向量矩阵,训练集标签向量,x轴名称,y轴名称,标题)def show(inX,dataSet,labels,xlab,ylab,tit): #用shape[0]读取训练集第一维的长度(行数即训练集实例数) dataSetRow=dataSet.shape[0] #用shape[1]读取训练集第二维的长度(列数即特征数) dataSetCol=dataSet.shape[1] #读取输入向量的列数(特征数) inXCol=len(inX) #训练集标签向量的个数 labelsLen=len(labels) #对训练集的判定 if labelsLen!=dataSetRow: print "训练集的特征集和标签集实例数目不等" return #对维度的判定 if dataSetCol!=2: print "特征不是两维的,暂时不能用这个方法" return #对输入实例的判定 if inXCol!=dataSetCol: print "用于测试的的实例的特征数目和训练集特征数目不等" return #绘制窗口 plt.figure(0) #横纵坐标名称,标题名称 plt.xlabel(xlab) plt.ylabel(ylab) plt.title(tit) #需要网格 plt.grid(True) #用来管理颜色表 idx=0 clr=['r','b','y','g','c','m'] bqzd={} #循环画每一个点(实际上也可以传入list画一群点) for i in range(labelsLen): #如果这个标签没放入字典 if bqzd.get(labels[i],0)==0: bqzd[labels[i]]=clr[idx] #放入字典 idx=(idx+1)%6 #取新的颜色表下标 #绘制这个点 plt.scatter( dataSet[i][0], dataSet[i][1], color=bqzd[labels[i]], marker='x', label=labels[i]) #绘制给定的实例点 plt.scatter( inX[0], inX[1], color='k', marker='o', label='Test Data') plt.show() return
导入模块,然后使用它:
运行结果:
在这里我使用的是L2范数距离(欧式距离)的平方,开根号不影响比较大小。
此外,为了显示点的标签,可以用:
#右上角打标注plt.legend(loc = 'upper right')
但是这个程序里是每个点画一次,不是传入相同标签的点的集和,所以直接这样用结果是这样:
所以可以去改一下for循环,只对新发现的类的那个点传入label参数:
#循环画每一个点(实际上也可以传入list画一群点)for i in range(labelsLen): #如果这个标签没放入字典 if bqzd.get(labels[i],0)==0: bqzd[labels[i]]=clr[idx] #放入字典 idx=(idx+1)%6 #取新的颜色表下标 #绘制这个点 plt.scatter( dataSet[i][0], dataSet[i][1], color=bqzd[labels[i]], marker='x', label=labels[i]) else: #绘制这个点 plt.scatter( dataSet[i][0], dataSet[i][1], color=bqzd[labels[i]], marker='x')
为了不遮挡,放在左上角:
#左上角打标注plt.legend(loc = 'upper left')
阅读全文
0 0
- 【ML学习笔记】12:k-近邻算法的demo
- ML学习笔记-K-近邻值算法
- ML--K-近邻算法
- 如何优雅的ML(一) k-近邻算法
- ML算法一:K-近邻算法
- ML-kNN 多标签k近邻算法
- ML-kNN 多标签k近邻算法
- 机器学习笔记1-k近邻算法的实现
- k-近邻法KNN-机器学习ML
- 机器学习笔记之K近邻算法
- 机器学习实战笔记 K近邻算法
- 机器学习实战笔记:K近邻算法
- 机器学习实战笔记 k-近邻算法
- 【机器学习】k-近邻算法笔记
- 机器学习笔记:K-最近邻算法
- 机器学习笔记之K-近邻算法
- 机器学习实战笔记:k近邻算法
- 学习笔记34-k近邻算法
- 数据结构实验之查找二:平衡二叉树
- MySql 事务&锁机制
- Delphi中窗体的方法
- 0基础学Python(6) —— 关于装饰器
- Matlab代码实现图像的傅里叶变换
- 【ML学习笔记】12:k-近邻算法的demo
- python代码问题
- Mininet学习笔记
- 求数组中的第三大数
- 集成GoogleMap正确的签名打包姿势
- qt 遍历目录
- JavaScript Table排序
- 剑指Offer(五)用两个栈实现队列
- BZOJ 4589 Hard Nim(博弈论+FWT+快速幂)