kNN算法的python实现

注:本文基于python 2.7版本编写

kNN即为(K Nearest Neighbors)K近邻算法,属于监督学习。

kNN的算法可以简单理解为一个分类器,其大概过程如下:

  1. 计算待分类数据和已分类数据的距离
  2. 按照距离从小到大排序
  3. 根据用户传递的参数k,统计前k个距离中对应的各个目标分类数量,返回分类数量最多的标签

总的来说,也就是可以理解为按照距离远近,少数服从多数的概念。

下面看下代码实现:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from numpy import *
import operator
import sys

# 为了能够让系统识别中文,修改默认编码方式
if sys.getdefaultencoding() != 'utf-8':
    reload(sys)
    sys.setdefaultencoding('utf-8')

# 定义已分类数据集及对应标签
def createDataSet():
    group = array([[1.0, 1.0], [1.1, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

def classify(intX, dataSet, labels, k):
    rowSize = dataSet.shape[0] # 计算数据集的行变量长度,即数据集个数
    diffMat = dataSet - tile(intX, (rowSize, 1)) # 计算数据集和待分类数据的坐标距离,x1-x2
    sqDiffMat = diffMat ** 2 # 计算距离查的平方,(x1-x2)^2
    sqDis = sqDiffMat.sum(axis=1) # 计算横纵坐标平方差的和,(x1-x2)^2+(y1-y2)^2
    Dis = sqDis ** 0.5 # 开根号
    sortedDisIndex = Dis.argsort() # 对距离排序,不过这返回的是对应距离在数组的下标

    resultLabels={}
    for i in range(k): # 统计前k个距离对应的各个分类标签的数量
        # 获取前k个距离对应的分类标签
        # 这里之所以用数组下标是因为在已分类数据上,其下标和分类标签下标是一致的,一个点对应一个分类标签
        # 所以用距离的下标就能获取对应的分类标签
        vote = labels[sortedDisIndex[i]] 
        votecount = resultLabels.get(vote, 0) # 使用字典统计对应标签的数量
        resultLabels[vote] = votecount + 1

    # 将字典按照各个分类标签的数量进行从大到小排序
    sortedClass = sorted(resultLabels.iteritems(), key=operator.itemgetter(1), reverse=True)

    return sortedClass[0][0] # 返回标签数量最多的对应的分类标签

如果有不懂的函数,可以参看下列链接:
shape函数
tile函数
sum函数
argsort函数
get函数
iteritems函数
itemgetter
sorted函数

测试代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import mykNN

rawData=[1,1.3]

dataSet, labels = mykNN.createDataSet()

print(mykNN.classify(rawData, dataSet, labels, 3))

对于kNN算法,有两个参数是模型正确率的关键,一个自然是k,另一个是距离的定义和计算。在这里,我们使用的是欧式几何距离,不过这只适用于连续变量。除此之外还有余弦距离、汉明距离、曼哈顿距离等等。

猜你喜欢

转载自blog.csdn.net/u010039418/article/details/81216018