K最近邻(kNN,k-NearestNeighbor):所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。
knn:在已有的数据集(dataSet)中,求目标点(input_data)与dataSet的欧式距离,根据计算好的欧式距离进行排序,从数据集中筛选出K个数据,通过比较k个数据所代表的分类(labels)的个数,来进行分类。
欧氏距离:(a,b),(c,d) d=sqrt((a-c)^2+(b-d)^2)
1.求input_data与dataSet中的欧氏距离即d=[d1,d2,d3]
2.对d进行排序,并取最小的K个点集dd
3.通过dd点集的labels来判断input_data的label分类
算法实现:
import numpy as np
def knn(input_data, dataSet, target, k):
dataSetSize = dataSet.shape[0]# get the row(number of dataSet) of the dataSet
diffMat = np.tile(input_data, (dataSetSize, 1)) - dataSet
#tile(input_data, (dataSetSize, 1)) is dataSetSize rows input_data,(a,b)-(c,d)
sqDiffMat = diffMat**2#((a-c)^2,(b-d)^2)
sqDistances = sqDiffMat.sum(axis=1)
#sum(axis=1) is to calcutate by rows,((a-c)^2+(b-d)^2)
distance = sqDistances**0.5
sort = distance.argsort()#get the sortedIndicies array
count = {}#sort by set
for i in range(k):
lab = target[sort[i]]
count[lab] = count.get(lab, 0) + 1
sortend = sorted(count.iteritems(), reverse=True)
return sortend[0][0]
if __name__ == '__main__':
group = np.array([[2, 2], [2, 1.5], [1.5, 2], [0, 0], [0, 0.5], [0.5, 0]])
labels = ['A', 'A', 'A', 'B', 'B', 'B']
print("the label of input_data is {0} ".format(knn([2, 2.5], group, labels, 3)))
output is :the label of input_data is A
使用iris数据集进行训练:
from sklearn import datasets
from sklearn.cross_validation import train_test_split
from sklearn.neighbors import KNeighborsClassifier
iris = datasets.load_iris()
data = iris.data[:, [2, 3]]
y = iris.target
x_train, x_test, y_train, y_test = train_test_split(data, y, test_size=0.3)
knn = KNeighborsClassifier(algorithm='auto')
knn.fit(x_train, y_train)
print "the predict labels are", knn.predict(x_test)
print "the real labels are", y_test
print "the score of knn is ", knn.score(x_test, y_test)
the predict labels are [1 0 1 2 2 2 2 2 2 0 1 1 0 0 2 2 1 2 0 1 1 0 2 0 1 2 0 2 1 0 1 1 1 2 0 0 1 1 0 0 1 2 1 0 0]
the real labels are [1 0 1 1 2 2 2 2 2 0 1 1 0 0 2 2 1 2 0 1 1 0 2 0 1 2 0 2 1 0 1 1 1 2 0 0 1 1 0 0 1 1 1 0 0]
the score of knn is 0.955555555556
可视化一下结果为: