【简介】
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合(来自百度百科)。
【最近邻算法】
最近邻算法通过计算预测点与测试样例点数据的欧式距离,找出待测数据与测试数据的最小欧式距离点,并返回该测试点的类型,从而确定预测数据类型的算法。
#coding:utf-8 import sys from numpy import * import operator import matplotlib.pyplot as plt def classify(input,dataSet,label): dataSize = dataSet.shape[0] ####计算欧式距离 tarry=tile(input,(dataSize,1));#生成dataSet一样的矩阵,进行剪发运算 diff = tarry - dataSet sqdiff = diff ** 2 #各参数平方(X²,Y²),得到距离 squareDist = sum(sqdiff,axis = 1)#行向量分别相加,从而得到新的一个行向量 X²,Y²相加, dist = list(squareDist ** 0.5) #开放,得到欧式距离 return label[dist.index(min(dist))] #返回最近邻 //找到距离最小值,并得与之对应的类型 dataSet = array([[0.1,2.8],[1.9,0.6],[1.0,2.0], [3.0,2.5],[2.0,2.5],[1.8,3.0], [0.1,0.1],[0.5,0.5],[1.5,0.5], [1.5,1.5],[1.7,0.1],[2.5,0.2], ]) labels = ['A','A','A','B','B','B','C','C','C','D','D','D'] input = array([1.9,0.5]) print("input = ",input) output = classify(input,dataSet,labels) print("class = ",output) plt.figure(figsize=(5,5)) for i,j in enumerate(dataSet): if labels[i] == 'A': plt.scatter(j[0],j[1],marker ="^",c="blue",s=80) elif labels[i] == 'B': plt.scatter(j[0],j[1],marker ="D",c ="green",s=80) elif labels[i] == 'C': plt.scatter(j[0],j[1],marker ="o",c ="darkorange",s=80) elif labels[i] == 'D': plt.scatter(j[0],j[1],marker ="s",c ="purple",s=80) plt.scatter(input[0],input[1],marker ="*",c ="red",s=200) plt.axis('tight') plt.show()
结果:
【K近邻算法】
最近邻算法的最大缺陷是对干扰数据过于敏感,为了解决这个问题,我们可以把未知样本周边的多个邻近样本计算在内,扩大参与决策的样本量,以避免个别数据直接决定决策结果。由此,我们引进K-最近邻算法(KNN)。K近邻算法是最近邻算法的一个延伸。思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。一般情况下,在分类时较大的K值能够减小干扰数据的影响。
#coding:utf-8 import sys from numpy import * import operator import matplotlib.pyplot as plt ###通过KNN进行分类 def classify(input,dataSet,label,k): dataSize = dataSet.shape[0] ####计算欧式距离 diff = tile(input,(dataSize,1)) - dataSet sqdiff = diff ** 2 squareDist = sum(sqdiff,axis = 1)###行向量分别相加,从而得到新的一个行向量 dist = squareDist ** 0.5 ##对距离进行排序 sortedDistIndex = argsort(dist)##argsort()根据元素的值从大到小对元素进行排序,返回下标 classCount={} for i in range(k): voteLabel = label[sortedDistIndex[i]] ###对选取的K个样本所属的类别个数进行统计 classCount[voteLabel] = classCount.get(voteLabel,0) + 1 ###选取出现的类别次数最多的类别 maxCount = 0 for key,value in classCount.items(): if value > maxCount: maxCount = value classes = key return classes dataSet = array([[0.1,2.8],[1.9,0.6],[1.0,2.0], [3.0,2.5],[2.0,2.5],[1.8,3.0], [0.1,0.1],[0.5,0.5],[1.5,0.5], [1.5,1.5],[1.7,0.1],[2.5,0.2], ]) labels = ['A','A','A','B','B','B','C','C','C','D','D','D'] input = array([1.9,0.5]) print("input = ",input) for K in range(1,13): output = classify(input,dataSet,labels,K) print("K = ",K,"class = ",output) plt.figure(figsize=(5,5)) for i,j in enumerate(dataSet): if labels[i] == 'A': plt.scatter(j[0],j[1],marker ="^",c="blue",s=80) elif labels[i] == 'B': plt.scatter(j[0],j[1],marker ="D",c ="green",s=80) elif labels[i] == 'C': plt.scatter(j[0],j[1],marker ="o",c ="darkorange",s=80) elif labels[i] == 'D': plt.scatter(j[0],j[1],marker ="s",c ="purple",s=80) plt.scatter(input[0],input[1],marker ="*",c ="red",s=200) plt.axis('tight') plt.show()