机器学习---kNN算法

来源:互联网 发布:协同过滤推荐算法原理 编辑:程序博客网 时间:2024/05/22 14:33

按照《机器学习实战》学习第一个算法kNN,由于自己刚接触python,所以直观上看不懂这个算法。然后就自己一行行的打印log,算是理解了,在此记录一下。

这个算法的目的,就是将现有的数据向量进行集合,然后看目标点与现有集合中向量的距离,选取k个集合比较,最近的便是目标向量的集合。

一.整个算法如下:

from numpy import *
import operator

def createDateSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group, labels

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()
    classCount={}
    for i in range(k):
        voteIlables = labels[sortedDistIndicies[i]]
        classCount[voteIlables] = classCount.get(voteIlables, 0) + 1
    sortedClassCount = sorted(classCount.iteritems(),
        key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


二.然后我们一步步的看

先初始化初始的数据集合

>>> import kNN
>>> group, labels = kNN.createDateSet()

得到4x2的矩阵group,代表当前的向量集合

>>> group
array([[ 1. ,  1.1],
       [ 1. ,  1. ],
       [ 0. ,  0. ],
       [ 0. ,  0.1]])


的到一个4x1的矩阵labels,与group对应起来,作为标签。

>>> labels
['A', 'A', 'B', 'B']


然后我们输入目标向量[0,0],找前3个集合比较

>>> kNN.classify0([0,0, group, labels, 3)

具体执行情况是

    dataSetSize = dataSet.shape[0] 

  // 得到已有向量集合的个数,就是4


    diffMat = tile(inX, (dataSetSize,1)) - dataSet

   // 将目标向量复制4个,与已知4个向量进行减法

//得到 array([[-1. , -1.1],

                      [-1. , -1. ],
                     [ 0. ,  0. ],
                     [ 0. , -0.1]])


    sqDiffMat = diffMat**2

// 求向量平方,得到

array([[ 1.  ,  1.21],
       [ 1.  ,  1.  ],
       [ 0.  ,  0.  ],
       [ 0.  ,  0.01]])


    sqDistances = sqDiffMat.sum(axis=1)

// 每个向量的2个值相加,用的是勾股定理,得到

array([ 2.21,  2.  ,  0.  ,  0.01])


    distances = sqDistances**0.5

// 再取平方根,得到4个距离

array([ 1.48660687,  1.41421356,  0.        ,  0.1       ])


    sortedDistIndicies = distances.argsort()

//对距离从小到大排序,序号从0开始

array([2, 3, 1, 0]),

对应上面的实际距离排序就是

array([ 0,   0.1,    1.41421356,   1.48660687])


classCount={}
    for i in range(k):
        voteIlables = labels[sortedDistIndicies[i]]
        classCount[voteIlables] = classCount.get(voteIlables, 0) + 1

// 这个循环的目的是得到一个排序后的集合,内容是标签+次数,

//得到的集合是

{'A': 1, 'B': 2}

    sortedClassCount = sorted(classCount.iteritems(),
        key=operator.itemgetter(1), reverse=True)

//再对刚才的集合从大到小排序,得到

[('B', 2), ('A', 1)]

//可以看到,与B最近,出现了2次。

因此得到的结果就是'B'。

直观上看,向量[0,0],的确与2个B [0,0],[0,0.1]是最近的。

因此目标向量属于B类。


0 0
原创粉丝点击