摘要:

K近邻算法是一种自动判别测试数据类型的算法,它是基于数据集的特征来进行分类,并不需要计算出数据预测模型,属于惰性算法。


算法介绍:

简单来说就是将测试数据与不用类别之间向量距离进行计算来进行分类

优点:精度高,异常值不敏感没有数据输入的假定

缺点:计算复杂度高,空间复杂度高

适用类型:数值型和标称型


算法过程:

存在一个样本的数据集合,同时数据集合带有标签。就是知道测试数据集合和所属的类别对应关系。输入没有标签的数据后,将新的数据每个特征和样本集中数据对应的特征比较,然后提取最相近的K个数据,将这个K个数据重出现次数最多的作为新数据的分类。

用Python语言进行开发的时候过程总结如下:

收集数据:任意

准备数据:距离计算

分析数据:任何

训练算法:

测试算法:计算错误率

使用算法:运行K近邻来判断输入样本所属的类别


第一步:使用Python导入数据

用模块化的方式编写载入数据的py,命名为kNN.py

from numpy import*
 import operator
 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

通过sys模块导入当前导入数据的模块文件的位置

可以用下述程序检验数据的导入

>>> import kNN
 >>> group,labels = kNN.createDataSet()
 >>> group,labels(array([[ 1. ,  1.1],
        [ 1. ,  1. ],
        [ 0. ,  0. ],
        [ 0. ,  0.1]]), ['A', 'A', 'B', 'B'])

这里有4组数据

labels是每组数据的标签信息,而每组数据是二维的数据


第二步:使用kNN算法

那么需要的算法步骤就是为每组数据分类

简单总结步骤如下:
计算已经类别和当前点之间的距离

然后选择距离最小的K个点

确定这K个点中频率次数出现最多的类作为当前点的预测分类

首先需要numpy中一些函数比如tile是重复参数1的各个维度


<span style="font-family: 'microsoft yahei'; line-height: 26px; background-color: rgb(255, 255, 255);">tile([1,2],(2,2)) = [[1,2,1,2],[1,2,1,2]]</span>


<span style="font-family: 'microsoft yahei'; line-height: 26px; background-color: rgb(255, 255, 255);">输出[1,2,1,2]</span>
 
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">而下文所用的argsort类似与统计方法中arg的用法返回的是下标,排序后的小标</span>


而下面的sum的时候axis=1

<span style="font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 14px; line-height: 21px;">以后就是将一个矩阵的每一行向量相加其实就是将x,y分量差相加0轴为列1轴为行</span>



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):                                         #选择最近的K个点
		voteIlabel = labels[sortedDistIndicies[i]]
		classCount[voteIlabel] = classCount.get(voteIlabel,0)+1   #若不是字典中的以0来代替
	sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse = True)  #排序按照第1维来进行并以数组形式存储
	return sortedClassCount[0][0]



通过这个算法进行预测

>>> group,labels = kNN.createDataSet()
 >>> kNN.classify0([0,0],group,labels,3)
 'B'

以上算法构造除了第一个分类器