KNN算法-小明逆袭的故事(1)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaohuigou1786/article/details/78466017

def classify0(inX,dataSet,labels,k):
    m=np.shape(dataSet)[0]
    diffMat=np.tile(inX,(m,1))-dataSet
    squareDiff=diffMat**2
    squareDist=squareDiff.sum(axis=1)
    dist=squareDist**0.5
    sortIndex=np.argsort(dist)
    classCount={}
    for i in range(k):
        currLabel=labels[sortIndex[i]]
        classCount[currLabel]=classCount.get(currLabel,0)+1
        sortedClass=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClass[0][0]

KNN算法:

K-近邻(KNN)算法在机器学习中是最基本的算法,简单且易于理解,经常作为机器学习入门的第一个算法。虽然KNN算法简单,但其中蕴含着丰富的机器学习思想,且在手写体数字识别方面有很好的效果,下面以一个有趣的例子来详细解释一下KNN算法。

小明是个邮递员

  小明,一个特别熟悉的名字。在小学以及中学课本里屡见不鲜,但是自从上了高中和大学以后,我们再也没有见过他,那他干什么去了呢?据说他去做了快递员,而且因为做快递而迎娶白富美,走上人生巅峰。那他是怎么做到的呢,下面让我们来一一分析:

  上面说到小明退学以后,因为学历不高,家里就给他找了一份快递员的工作。但他的工作并不是普通的送快递,而是把别人发的快递录入系统(假设小明工作时,快递的录入都需要人工),而小明仅仅需要把快递单号录入系统就行,而且小明的工资与录入的件数有关,也就是小明录入的越多,工资越多!话说小明刚开始工作时还挺有兴趣的,加上工作也不难,但是时间长了以后,小明对每天这麽重复的工作就产生了厌烦。小明后来就想对于录入数字这麽简单的工作会不会有程序来代替它,就是我们输入每个数字的图片,然后可以通过程序直接得到对应的数字。自从有个这个想法以后,小明每天都在思考有没有程序可以代替自己现在的工作。终于一个偶然的机会小明知道了KNN算法,KNN算法是一个特别简单的分类算法,可以对输入进行分类。这时候小明突然想到自己的工作不就是对图片的数字进行分类,具体就是分为0——9.小明有了这个想法以后就抱着试试看的态度写了一个小程序,用的是Python,关于小明为什么选择Python,那只有他自己知道了。

  在看了几天的KNN算法以后,小明对KNN有了一定的了解。其实KNN算法就是一个简单的根据相似度对输入进行分类的算法,当然首先我们需要一定的输入数据,输入数据包括数字图片和其对应的数字,例如我们需要输入数字5的手写体图片,还有对应的数字5.在输入了大量的数据以后,在这些数据中就隐含着对数字图片的分类信息。在这些信息中有一个特别有意思的事是同样的数字,他们的距离最近(一般选择欧式距离,后面会讲到)。我们使用一个简单的例子说明一下:有一个数字5的图片,我们可以把这个图片表示成一个矩阵,具体的大小就是像素数。然后我们可以把这个图片展开成一个向量表示,例如一个图片的大小为32×32,然后我们就可以把这个图片展开成一个1×1024的行向量。而这个行向量有具体的分类标签,即数字5;然后我们不仅仅有数字5的图片,还有0-9其他数字的,假设我们共有500个数据,即数字图片还有对应的类别(0-9)。然后我们把其中400个样本放入KNN中,然后剩余100个数字图片,当然这些图片也是有对应的数字类别的,而这100个数字图片我们就可以用来估计整个KNN模型的准确度。

  在KNN中,当小明有了500个数字图片还有其类别标签以后,小明发现不知道怎么去定义两个向量的距离,在查阅了很多资料以后,他突然发现有很多定义距离的方法,例如欧式距离,关于欧式距离,小明刚开始根本不知道是什么,后来看了表达式以后,突然发现就是中学中已经学过的距离定义,只不过当时他的数学老师只让他会计算,并没有讲更深入的东西。当看到这的时候小明有点蠢蠢欲动,因为他发现整个算法的核心在自己初中的时候已经学过了,想自己动手实现,但是虽然小明的学历不高,但是却有很强的贝叶斯思维,所以他想先用个简单的例子来证明自己的KNN程序是对的,然后再把自己的程序应用于工作中。

  首先小明写了一个简单的例子来实现KNN,对于一组简单的二维空间中的数据,小明想对它进行分类,首先小明自己定义了几组数据并且有对应的分类标签。数据为{(1,1),(1.1,1.0),(0,0),(0,0.1)},分类标签为:【A,A,B,B】:下面小明想看一下自己的数据(毕竟维数比较低,很容易进行可视化)

import numpy as np
def createDataSet():
    group=np.array([[1.0,1.0],[1.1,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels
然后小明对数据进行了可视化:

从图中可以看出两组不同的数据,而不同组的数据有不同的类别。然后小明有了最基本的数据以后就开始了最艰难的旅程--实现KNN算法:

扫描二维码关注公众号,回复: 3104479 查看本文章
def classify0(inX,dataSet,labels,k):
    m=np.shape(dataSet)[0]
    diffMat=np.tile(inX,(m,1))-dataSet
    squareDiff=diffMat**2
    squareDist=squareDiff.sum(axis=1)
    dist=squareDist**0.5
    sortIndex=np.argsort(dist)
    classCount={}
    for i in range(k):
        currLabel=labels[sortIndex[i]]
        classCount[currLabel]=classCount.get(currLabel,0)+1
        sortedClass=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClass[0][0]


然后小明对自己简单的KNN算法进行测试:

print KNN.classify0([0.0,0.4],dataSet,labels,3)
最后的输出结果是B,然后小明又进行了几次测试,最后结果都是正确的,说明自己的程序是没有错误的。

完整的代码如下:

import numpy as np
import operator
def createDataSet():
    group=np.array([[1.0,1.0],[1.1,1.0],[0,0],[0,0.1]])
    labels=['A','A','B','B']
    return group,labels

def classify0(inX,dataSet,labels,k):
    m=np.shape(dataSet)[0]
    diffMat=np.tile(inX,(m,1))-dataSet
    squareDiff=diffMat**2
    squareDist=squareDiff.sum(axis=1)
    dist=squareDist**0.5
    sortIndex=np.argsort(dist)
    classCount={}
    for i in range(k):
        currLabel=labels[sortIndex[i]]
        classCount[currLabel]=classCount.get(currLabel,0)+1
        sortedClass=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClass[0][0]

dataSet,labels=createDataSet()
print classify0([0.0,0.4],dataSet,labels,3)
小明测试完代码以后抬起头看了看时间,此时已经是夜里十二点钟了,想到明天还要继续自己手动录入快递单号,突然若有所思。



猜你喜欢

转载自blog.csdn.net/xiaohuigou1786/article/details/78466017