首页 > 代码库 > 机器学习实战之kNN

机器学习实战之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=http://www.mamicode.com/(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