1. 算法原理
训练样本集中的每个数据都存在标签,输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行距离的计算,并将距离进行排序,选取k个最相似数据中出现次数最多的类别作为新数据的类别。
2. 算法优缺点
优点:精度高、对异常值不敏感
缺点:计算复杂度高(与样本大小n成正比)、空间复杂度高
是一种消极学习方法,基本上不需要学习的过程。这种学习方式指不是根据样本建立一般化的目标函数并确定其参数,而是简单地把训练样本存储起来,直到需要分类新的实例时才分析其与所存储样例的关系,据此确定新实例的目标函数值。也就是说这种学习方式只有到了需要决策时才会利用已有数据进行决策。KNN就属于这种学习方式。
3. 距离度量
欧氏距离、曼哈顿距离、明可夫斯基距离
4. K值的影响
KNN中K值是需要自己指定的,关于K值大小对预测结果的影响如下:
若K值太小,相当于用较小的邻域中的训练样本去预测,则KNN分类器容易受到由于训练数据中噪声的影响而产生过拟合。
若K值太大,因为邻域比较大,则与测试样本距离较远的训练样本也会起作用,这样会导致误分类测试样本。
若K = N,那么无论输入的测试样本是什么,输出都会是训练样本中样本数量最多的类,这种模型基本没什么用。
在实际应用中,k值一般选取一个比较小的值,可以通过交叉验证法来选取最优的K值。
5. 应用场景
字符识别、文本分类、图像识别等领域。
6. 案例
简单实例
from numpy import * #导入numpy科学计算包
# 准备数据
# 使用的是电影数据,搞笑镜头、拥抱镜头、打斗镜头,label是电影类型
movie_data = {"宝贝当家": [45, 2, 9, "喜剧片"],
"美人鱼": [21, 17, 5, "喜剧片"],
"澳门风云3": [54, 9, 11, "喜剧片"],
"功夫熊猫3": [39, 0, 31, "喜剧片"],
"谍影重重": [5, 2, 57, "动作片"],
"叶问3": [3, 2, 65, "动作片"],
"伦敦陷落": [2, 3, 55, "动作片"],
"我的特工爷爷": [6, 4, 21, "动作片"],
"奔爱": [7, 46, 4, "爱情片"],
"夜孔雀": [9, 39, 8, "爱情片"],
"代理情人": [9, 38, 2, "爱情片"],
"新步步惊心": [8, 34, 17, "爱情片"]}
# 引入新的数据
x = [23, 3, 17]
# 搞笑镜头=23、拥抱镜头=3、打斗镜头=17
# 计算新的数据到各个数据的欧氏距离
KNN = []
for key, v in movie_data.items():
d = math.sqrt((x[0] - v[0]) ** 2 + (x[1] - v[1]) ** 2 + (x[2] - v[2]) ** 2)
KNN.append([key, round(d, 2)])
# print(KNN)
# 得到的KNN=电影名,新数据到当前电影的欧氏距离
# 对距离进行排序
KNN.sort(key=lambda dis: dis[1])
# 得到最短的k个=5个,选择其中出现次数最多的类别作为新数据的类别
KNN=KNN[:5]
labels = {"喜剧片":0,"动作片":0,"爱情片":0}
for s in KNN:
label = movie_data[s[0]] #取出电影对应的类别 label[3]就是对应的类别
labels[label[3]] += 1
labels =sorted(labels.items(),key=lambda l: l[1],reverse=True)
# print(labels,labels[0][0],sep='\n')
print("新数据的类别是:"+str(labels[0][0]))
输出结果是:
新数据的类别是:喜剧片