KNN(K邻近)算法

k-邻近算法的一般流程

  1. 收集数据:可以使用任何方法
  2. 准备数据:距离计算(应该是计算距离)所需要的数值,最好是结构化的数据格式
  3. 分析数据:可以使用任何方法
  4. 训练算法: 此步骤不适用与k-邻近算法
  5. 测试算法:计算错误率
  6. 使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-邻近算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理
# -*- coding: utf-8 -*-

# 创建名为kNN.py的Python模块
from numpy import * # 导入科学计算包NumPy
import operator # 导入运算符模块

# 导入数据的函数,该函数返回 group 和 labels
def createDataSet():
    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] 
    # 计算array的维度,array(4,2),array.shape=(4,2),shape[0]=4
    #dataSetSize = 4

    diffMat = tile(inX, (dataSetSize, 1)) - dataSet 
    # tile功能是重复某个数组,tile(A,n).tile(A,(2,1))重复得到的数组是一个二维数组
    # diffMat :
        # [-1. , -1.1],
        # [-1. , -1. ],
        # [ 0. , 0. ],
        # [ 0. , 0.1]

    sqDiffMat = diffMat ** 2 
    # 计算每个特征值与inX点值的差值的平方
    # sqDiffMat:
        # [1. , 1.21],
        # [1. , 1. ],
        # [0. , 0. ],
        # [0. , 0.01],

    sqDistances = sqDiffMat.sum(axis=1) 
    # sum of each row,if axis=0:sum of each column
    # sqDistances:
    # 该步骤的运算结果为:[ 2.21, 2. , 0. , 0.01]

    distances = sqDistances ** 0.5
    # 计算欧式距离,即xA(xA0, xA1)和xB(xB0, xB1)之间的距离
    # d = sqrt((xA0-xB0)^2) + (xA1-xB1)^2)
    # 例如:点(0, 0)与(1,2)之间的距离计算为:
    # sqrt( (1 - 0)^2 + (2 -0)^2 )
    # 这一步的运算结果为:[ 1.48660687, 1.41421356, 0. , 0.1 ]

    sortedDistIndicies = distances.argsort()
    # numpy.argsort(a, axis=-1, kind='quicksort', order=None)
    # 这一步的运算结果为:[2, 3, 1, 0],即sortedDistIndicies[2] < sortedDistIndicies[3] < sortedDistIndicies[1] < sortedDistIndicies[0],
    ''' One dimensional array: >>> x = np.array([3, 1, 2]) >>> np.argsort(x) array([1, 2, 0]) Two-dimensional array: >>> x = np.array([[0, 3], [2, 2]]) >>> x array([[0, 3], [2, 2]]) '''

    classCount = {}
    # classCount 是字典

    for i in range(k):
        m = sortedDistIndicies[i]
        # 当i=0时,sortedDistIndicies[0] = 2

        voteIlabel = labels[m]
        # voteIlabel = B

        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
        # dict.get(key, default=None)
        # key -- 字典中要查找的键。
        # default -- 如果指定键的值不存在时,返回该默认值值
        # 返回指定键的值,如果值不在字典中返回默认值None

    # 循环结束后的结果为:
    # classCount = {'A': 1, 'B': 2}

    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse= True)
    # itemgetter(1)方法按照第二个元素的次序对元组进行排序,
    # reverse表示逆序,结果为:[('B', 2), ('A', 1)]

    return sortedClassCount[0][0]

if __name__ == '__main__':
    group, labels = createDataSet()
    print classify0([0, 0], group, labels, 3)

输出的结果是: B

你可能感兴趣的:(python,机器学习,k-邻近)