KNN算法及其实现

来源:互联网 发布:马鞍山知谷教育图片 编辑:程序博客网 时间:2024/06/06 01:34

    K-邻近算法(k-NearestNeighbor,KNN),存在某一样本集,已经知道样本和对应的类别,当输入一个没有类别标识的数据时,找出与其“最相似”的K个样本,在这k个样本中,哪个类别的样本个数最多,我们就把该未知数据的类别归为此类。其中的相似性,可以利用距离来度量,而衡量距离的方法,可以是欧氏距离,闵可夫斯基距离,曼哈顿距离等等。

    KNN算法步骤:

    1,与处理数据

    2,根据距离公式求出,未知数据,到其他每个样本的距离

    3,把距离排列,选出距离最小的k个样本

    4,投票决定,该未知数据属于哪一个类别。

   一下根据实战来简单实现一下KNN。

# -*- coding: utf-8 -*-"""Created on Sat Mar 04 17:34:27 2017@author: Abner"""from numpy import*import operatordef createDataSet():    group = array([[0, 1], [1.0, 1.0], [0, 0], [1, 1]])    labels = ['A', 'A', 'B', 'B']    return group, labels    def KNNclassify(inputData, dataSet, labels, k):    DataSetRow = dataSet.shape[0]    expandInputData = tile(inputData, (DataSetRow, 1))        difference = expandInputData - dataSet    sqdiff = difference**2    tempSum = sqdiff.sum(axis = 1)    distance = tempSum**0.5        disIndex = distance.argsort()    countNum = {}        for i in xrange(k):        voteLable = labels[disIndex[i]]        countNum[voteLable] = countNum.get(voteLable, 0) + 1    kNNDistance = sorted(countNum.iteritems(), key = operator.itemgetter(1), reverse = True)        return kNNDistance[0][0]        group, labels = createDataSet()print  KNNclassify([1, 0.2], group, labels, 3)


解释一下这段代码:

    首先生成一个样本集,本例生成了四个点,以及每个点所对应的类别。我们的距离度量为欧氏距离。

def createDataSet():    group = array([[0, 1], [1.0, 1.0], [0, 0], [1, 1]])    labels = ['A', 'A', 'B', 'B']    return group, labels

    1,处理数据

 DataSetRow = dataSet.shape[0]#多少个样本数据,也就是多少行    expandInputData = tile(inputData, (DataSetRow, 1))#把未知数据,扩展为和样本数据一样的维数

    这里有必要说一下tile(A,reps) 这个函数,tile函数会把A按照reps从后向前依次对维度扩展,比如:

    A = [11, 12, 13], tile(A, 2),就是把A沿着第一个维度扩展依次,扩展的宽度就是原始列表的长度,于是:

A = [11, 12, 13]print tile(A, 2)[11 12 13 11 12 13]
    tile(A, (2, 1)),A的第一个维度不变,第二个维度扩展一次。

A = [11, 12, 13]print tile(A, (2, 1))[[11 12 13] [11 12 13]]

    tile(A, (2, 2, 2)),A的第一维,第二维,第三维各扩展一次
A = [11, 12, 13]print tile(A, (2, 2, 2))[[[11 12 13 11 12 13]  [11 12 13 11 12 13]] [[11 12 13 11 12 13]  [11 12 13 11 12 13]]]

   ,2,然后,求输入数据到训练样本的距离。

#计算距离    difference = expandInputData - dataSet    sqdiff = difference**2    tempSum = sqdiff.sum(axis = 1)#按行求和    distance = tempSum**0.5

   3,把距离排序

    disIndex = distance.argsort()#不改变原始数据,但是会返回,数据从小到大排好后,在原始的位置
    argsort()函数,可看如下例子:

a = [11, 56, 3, 1, 88, 33, 96, 2]index = argsort(a)print indexprint a[3 7 2 0 5 1 4 6][11, 56, 3, 1, 88, 33, 96, 2]

    4,求距离最近的K个样本

    countNum = {}    for i in xrange(k):        voteLable = labels[disIndex[i]]        countNum[voteLable] = countNum.get(voteLable, 0) + 1    kNNDistance = sorted(countNum.iteritems(), key = operator.itemgetter(1), reverse = True)
    .get()函数,.get(key, default),如果key值存在,get就返回相应的value,如果不存在就返回defult。例如:

dic = {"jack":15, "tom":20}print dic.get("jack", 0)print dic.get("jerry", 0)150
    sorted函数,请看:http://blog.csdn.net/hearthougan/article/details/60361126
    5,输出类别

kNNDistance[0][0]

    从上述的代码中步骤中,我们可以看出来,每当输入一个数据,我们要计算该数据到每个样本的额距离,如果样本量很大,那么KNN的效率会很低。


1 0
原创粉丝点击