K-近邻算法(KNN)简述

KNN是通过测量不同特征值之间的距离进行分类。它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别,其中K通常是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

下面通过一个简单的例子说明一下:如下图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

KNN算法解决的题目 knn算法例题_欧氏距离

由此可以看出kNN算法的结果很大程度上取决于k的选择。

在kNN中,通过计算对象距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧氏距离或曼哈顿距离:
KNN算法解决的题目 knn算法例题_曼哈顿距离_02
KNN算法解决的题目 knn算法例题_测试数据_03

总结

就是在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前K个数据,则该测试数据对应的类别就是K个数据中出现次数最多的那个分类,其算法的描述为:

(1) 计算测试数据与各个训练数据之间的距离;

(2) 按照距离的递增关系进行排序;

(3) 选取距离最小的K个点;

(4) 确定前K个点所在类别的出现频率;

(5) 返回前K个点中出现频率最高的类别作为测试数据的预测分类。

代码实现

#-*- coding:utf-8 -*-
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

#通过kNN进行分类
def classify(input, dataSet, label, k):
	dataSize = dataSet.shape[0]
	#tile在列向量方向上重复input共1次(横向),行向量方向上重复input共dataSetSize次(纵向)
	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):
		#取出前k个元素的类别
		voteLabel = label[sortedDistIndex[i]]
		#对距离最近的k个样本所属类别进行统计
		#dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。
		classCount[voteLabel] = classCount.get(voteLabel,0) + 1

	#python3中用items()替换python2中的iteritems()
    #key=operator.itemgetter(1)根据字典的值进行排序
    #key=operator.itemgetter(0)根据字典的键进行排序
    #reverse降序排序字典
	sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
	#返回次数最多的类别,即所要分类的类别
	return sortedClassCount[0][0]

if __name__ == '__main__':
	dataSet,labels = createDataSet()
	input = array([0, 0.3])
	K = 3
	output = classify(input,dataSet,labels,K)
	print("测试数据为:",input,"分类结果为:",output)