KNN算法的目的
KNN算法,即给定一定数量的已知类别,并以此作为依据,根据未知实例与k个最近的已知类别中哪个已知类别占主导,来预估未知实例的类别。
KNN算法的大致流程
- 确定k的值(即几个距离未知样本最近的已知样本)
- 计算未知样本与所有已知样本的距离
- 选择k个最近的已知样本
- 根据少数服从多数,把未知样本归类于k个最近已知样本中最多数的类别
一个小小的栗子
假设我们要建立一个模型,用来估测未知的那个电影,是属于爱情片还是打斗片,下面是已知数据
建立模型
画出图像
黑点即我们要预测的对象,最红通过选定k个离他最近的点即可得到预估结果。
算法缺点
- 算法复杂度较高(因为需要计算未知样本与所有已知样本的距离)
- 当样本分布不平衡时,新的未知样本容易被归类为占据主导的已知样本的类别。
python实现
数据还是上文小栗子中的数据
我们先把上述的栗子画出图例
import matplotlib.pyplot as plt
import numpy as np
import operator
#已知的分类数据
x1=np.array([3,2,1])
y1=np.array([104,100,81])
x2=np.array([101,99,98])
y2=np.array([10,5,2])
scatter1=plt.scatter(x1,y1,c='r')
scatter2=plt.scatter(x2,y2,c='b')
#未知数据
x=np.array([18])
y=np.array([90])
scatter3=plt.scatter(x,y,c='k')
#画图例
plt.legend(handles=[scatter1,scatter2,scatter3],labels=['lableA','lableB','X'],loc='best')
plt.show()
knn大致流程
#已知分类的数据
x_data=np.array([
[3,104],
[2,100],
[1,81],
[101,10],
[99,5],
[98,2],
])
y_data=np.array(['A','A','A','B','B','B'])
x_test=np.array([18,90])
#计算已知样本的数量
x_data_size=x_data.shape[0]
#计算x_test与每一个样本的差值
diffMat=np.tile(x_test,(x_data_size,1))-x_data #先将x_test复制六份,再计算其与已知
# 计算差值的平方
sqDiffMat=diffMat**2
print(sqDiffMat)
#求和
sqDistances=sqDiffMat.sum(axis=1)
#开方(得到欧氏距离)
distances=sqDistances**0.5
#将距离从小到大排序(得到的是索引的值)
sortedDistance=distances.argsort()
classCount={}#创建字典
# 设置k
k=5
for i in range(5):
#获取标签
votelabel=y_data[sortedDistance[i]]
#统计标签数量
classCount[votelabel]=classCount.get(votelabel,0)+1
#按照值对classCount从小到大排序,然后取倒序
sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
#获取数量最多的标签
knnclass=sortedClassCount[0][0]