机器学习实战之kNN
Posted 落花盈香
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习实战之kNN相关的知识,希望对你有一定的参考价值。
笔者最近开始对机器学习非常感兴趣,作为一个有志向的软设方向的女孩纸,我开始了学习的第一步入门,下面将今天刚刚学习的kNN及其应用进行总结和回顾,希望可以得到更好的提升,当然,有志同道合者,你可以联系我给我留言,毕竟菜鸟一起飞才能飞的更高更远。??
首先,kNN算法也叫k-近邻算法,它的工作原理是:存在一个样本的数据集合,也称作训练样本集,并且每个样本集都有其标签。故而,我们很清楚每一数据和其所属分类之间的关系。当输入新样本时,我们将新数据的每一个特征样本集中对应的数据特征进行比较,然后算法提取特征集中特征最相似的数据(k个)。然后在k个值中找分类的众数,作为新数据的类别预测。
kNN算法的一般流程
(1)收集数据:可以使用任何方法
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式
(3)分析数据:可以使用任何方法
(4)训练方法:此步骤不适合kNN算法
(5)测试算法:计算错误率
(6)使用算法:进行预测
!代码如果不能允许将后面的注释删除即可,下面的函数全部写在一个叫kNN.py的文件里
1 程序清单 kNN算法(如果出现错误,去掉注释就行)输入在新建的kNN.py文件中 2 def classify0(inX,dataSet,labels,k):#inX为输入的被预测数据,dataSet和labels分别为已知数据的属性数据和分类,k为用于选择最近邻居的数目 3 dataSetSize=dataSet.shape[0]#获取测试数据的行号 4 diffMat=tile(inX,(dataSetSize,1))-dataSet#tite表示复制,整句表示的是复制data Size行,1列的意思,最后减去dataSet,即计算出每个维度相减的值 5 sqDiffMat=diffMat**2#算平方 6 sqDistances=sqDiffMat.sum(axis=1)#若axis=0,则为普通相加;若axis=1,则为行向量的一行相加 7 distances=sqDistances**0.5#算出该被预测点与其他点点距离 8 sortedDistIndices=distances.argsort()#将数组的下标按数据值从小到大的顺序输出 9 classCount={} 10 for i in range(k): 11 voteIlabel=labels[sortedDistIndices[i]] 12 classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#get函数表示如果classCount中存在,则取出值,否则返回0 13 sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True) 14 return sortedClassCount[0][0] 15
测试:在终端输入
import kNN
kNN.classify([0,0],group,labels,3) #这里也可以先不测试,我们往后看
既然我们已经写出了kNN算法的测试代码,那我们现在就要开始使用它,要是用它,我们首先要有数据,这个例子的数据可以去机器学习实战里找
给定的数据是txt文本的格式,我们为了进行处理,首先要将其转化为代码可以跑的格式,所以我们需要在我们创建的kNN.py中再加上以下函数,将数据格式进行转化
def file2matrix(filename): fr=open(filename) numberOfLines=len(fr.readlines())#计算文件中数据所占行数 returnMat=zeros((numberOfLines,3))#创建一个numberOfLines行,3列的矩阵 classLabelVector=[] fr=open(filename) index=0 for line in fr.readlines():#依次读出文件每行数据 line=line.strip()#去换行符 listFromLine=line.split(‘\t‘)#以tab键为分隔将数据转为列表 returnMat[index,:]=listFromLine[0:3]#将获取的值赋值到returnMat中 classLabelVector.append(int(listFromLine[-1]))#去最后一个列(即类别,也即最后的预测结果) index+=1 return returnMat,classLabelVector
备注:文件中每列三个属性,第四列为数据所属类别
测试:
import kNN
datingDataMat,datingLabels=kNN.file2matrix("datingTestSet.txt")
好吧,到这一步,我们已经成功的把数据输入到程序里,并转化为程序可以处理的形式,那么下一步,我们要进一步对数据进行处理,也被称之为归一化处理,那么,我们为什么要进行归一化处理呢?那是因为kNN算法是基于距离的算法,如果一个数据所具有的属性值太大,在计算距离时,必然造成其在整个值的比重偏大,然而我们的每个属性都应该具有相等的价值,故而我们要进行归一化处理,使每个属性在计算过程中所占比重相同。归一化所用公式为:newValue=(oldValue-min)/(max-min)
def autoNorm(dataSet): minVals=dataSet.min(0)#取每列最小值 maxVals=dataSet.max(0)#取每列最大值 ranges=maxVals-minVals normDataSet=zeros(shape(dataSet))#创建行列与dataSet相同的0矩阵 m=dataSet.shape[0]#取行数 normDataSet=dataSet-tile(minVals,(m,1))#计算oldValue-min normDataSet=normDataSet/tile(ranges,(m,1))#计算newValue return normDataSet,ranges,minVals#返回数据
测试:
import kNN
normMat,ranges,minVals=kNN.autoNorm(datingDataMat)
好,现在数据我们已经准备好了,那么就可以带入kNN算法使用啦,亲爱的们,准备好了吗?
def datingClassTest(): #test the correct ratio hoRatio=0.10 datingDataMat,datingLabels=file2matrix("datingTestSet2.txt") normMat,ranges,minVals=autoNorm(datingDataMat) m=normMat.shape[0] numTestVecs=int(m*hoRatio) errorCount=0.0 for i in range(numTestVecs): classifierResult=classify0(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.0 print "the total error rate is:%f" %(errorCount/float(numTestVecs))
到这里,我们对kNN算法的学习就结束了,下一章,我们对新的学习做新的总结,加油,未来总是美好哒??
以上是关于机器学习实战之kNN的主要内容,如果未能解决你的问题,请参考以下文章