KNN (K最近邻接算法)python 语言下的简单实现

来源:互联网 发布:淘宝网无线端装修 编辑:程序博客网 时间:2024/06/08 10:52

Machine Learning in Action 给出第一个小例子---最简单的分类器


只涉及最简单的向量知识,主要是python语言实现过程中有不理解的地方。

书中源代码如下


运行代码需要用到 numpy和 operator 模块,numpy一般要自行下载装载,用于代数操作。

 

shape是返回数组array的维度信息,如三维数组

>>> a=ones((2,3,4))

>>> a.shape[0]

2

>>> a.shape[1]

3

>>> a.shape[2]

4

 以上分别返回了数组的维度信息

 

tile(inX, (dataSetSize,1)) 得到的是dataSetSize个的inX,使用到tile函数。tile函数将inX按后面括号中的要求复制,(dataSetSize,1)可以理解为复制dataSetSize行 1列。括号中可以推广至多维。

 

如:

>>> a

array([[1, 2],

      [3, 4]])

>>> tile(a,(2,1))

array([[1, 2],

      [3, 4],

      [1, 2],

      [3, 4]])

>>> tile(a,(2,1,1))

array([[[1, 2],

       [3, 4]],

 

      [[1, 2],

       [3, 4]]])

>>> tile(a,(2,3,4))

array([[[1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4],

       [1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4],

       [1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4]],

 

      [[1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4],

       [1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4],

       [1, 2, 1, 2, 1, 2, 1, 2],

       [3, 4, 3, 4, 3, 4, 3, 4]]])

 

代码中使用diffMat=tile。。。计算了待分类样本与训练集的距离,相当于:

array1=([[x, x], [x, x], [x, x], [x, x]])

array2=([[1, 0], [1, 1], [00], [0, 2]])

其中每个向量直接相减。

diffMat**2 得到相减后的平方。

再使用 sum(axis=1)得到一个array中第二维所有项的和的少一维的array,维数为2时,正好是把所有向量的项相加,得到只有行数的向量。axis=1 可以理解为 维数为1的项不考虑了,取消维数1,将相应的项相加。

如 (1,2),(3,4),(5,6),(7,8),有二维(需要两个坐标,即两项的向量确定一个0540;),向量(X0,X1)可以确定一个0540;,(2,1)可以确定3。axis=1求sum,此时维数是2,则(axis有0,1)对应(X0,X1),不考虑axis=1,则axis=0不变,将1+2,3+4,。。得到(3),(7),(11),(15)的array,完成求和。

代码中,则可以得到样本与训练集的距离了。

 

 

distances.argsort() 中的argsort()函数,用于操作distances的array,可以将维数为1的distances里的元素从小到大排列,得到一个对应原来的元素的顺序的排列。

a为[100,400,999,44,68],a.argsort()返回一个[3,4,0,1,2]的序列。

 

classCount 用于计算样本对于K个训练数据的分类情况,统计属于哪个分类。

建立空的“字典”classCount,接下来是K个循环。循环对每个距离结果分类,并统计各个分类的数量(通过+1实现)

首先,sortedDistIndices[i]是对应的argsort得到的大小序列,再通过labels[sortedDistIndices[i]]得到从小到大的数据对应的分类,将分类名给到voteIlabel。classCount[voteIlabel]=创建出“分类”对应的字典中的0540;。classCount.get(voteIlabel,0)作用是返回字典中的0540;,若voteIlabel已经存在,则取出voteIlabel对应的0540;(分类次数)加1。若voteIlabel不存在,则此次已经创建出了,并且对应0540;返回0(即括号逗号后的0540;)加1 。则循环k次后可以统计完毕。

 

最后一行长长的函数意思是将classCount中的0540;排序,最大的排在最前面,此时得到一个从大到小排列后的字典,‘Romance’:10,‘Action’:2,则[0][0]取出最前的字典条目中的左边的名称,即对应的分类类型。

原创粉丝点击