一、KNN 简介
KNN(k-NearestNeighbor)又被称为近邻算法,它的核心思想是:物以类聚,人以群分。
1.算法步骤
(1)计算测试对象到训练集中每个对象的距离
其中距离的计算可采用欧氏距离 d = sqrt [ ∑( ( a - b )^2 ) ] (i = 1、2…n)
(2)按照距离从小到大排序
(3)选取与当前测试对象最近的K个训练对象
(4)统计这K个对象的类别概率
(5)这K个对象里频率最高的类别,即为测试对象的类别。
2.优缺点
优点:非常简单的分类算法,人性化,易于理解,易于实现,适合处理多分类问题。
缺点:属于懒惰算法,时间复杂度较高,因为需要计算未知样本到所有已知样本的距离,样本平衡度依赖高,当出现极端情况样本不平衡时,分类绝对会出现偏差。可解释性差,无法给出类似决策树那样的规则。向量的维度越高,欧式距离的区分能力就越弱。
二、代码实现
# 第一步:导入库
import numpy
import pandas as pd
import math
import matplotlib.pyplot as plt
# 第二步:确认训练集和测试样本
# 测试样本:泰坦尼克号[2,40, 9, '?']
# 训练集数据如下
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 = [3, 40, 9]
dist = []
for key, value in movie_data.items():
d = math.sqrt((x[0]-value[0])**2 + (x[1]-value[1])**2 + (x[2]-value[2])**2)
dist.append([key, round(d, 2)])
print(dist)
# 第四步:对距离大小按递增排序
dist.sort(key=lambda dis: dis[1])
print(dist)
# 第五步:选取距离最小的k个样本,选取k=5
mindist = dist[:5]
print(mindist)
# 第六步:确定前k个样本所在类别出现的频率,并输出出现频率最高的类别
label_times = {'喜剧片': 0, '动作片': 0, '爱情片': 0}
for s in mindist:
label = movie_data[s[0]][-1]
label_times[label] += 1
print(label_times)
print(label_times.items())
label_times_sorted = sorted(label_times.items(), key=lambda l: l[1], reverse=True)
print(label_times_sorted, label_times_sorted[0][0], sep='\n')
三、实验结果分析
对样本:泰坦尼克号[2,40, 9, '?'],进行测试
得出结论:距离最近的前五个对象中有1喜剧片 0动作片 4爱情片,所以测试样本为爱情片