1. 概述
k-近邻算法(k-Nearest Neighbour algorithm),又称为KNN算法,是数据挖掘技术中原理最简单的算法。KNN的工作原理:给定一个已知标签类别的训练数据集,输入没有标签的新数据后,在训练数据集中找到与新数据最邻近的k个实例,如果这k个实例的多数属于某个类别,那么新数据就属于这个类别。
可以简单理解为:由那些离X最近的k个点来投票决定X归为哪一类。
以一个案例来说明,每条数据都有多种特征,和最后的类型,那我们就可以根据新电影的特征数据来判断该电影的所属类别。
判断准则:采用欧式距离(也称欧几里得度)
公式中n表示数据的特征数量,x表示新数据,y表示已有数据,那对于一个具有a条已有数据,来判断新数据时,新数据需要和每个已有数据计算其欧式距离。
注意KNN算法中需要确定一个超参数k的值,有以下算出并排序之后的表来看(无问西东应该和前任3换一下位置),我们取k=4,则前4条内容中 爱情片出现的概率为75%,动作片出现的概率为25%,因此决策新电影为爱情片。
2. k-近邻算法步骤
(1) 计算欧式距离:计算已知类别数据集中的点与当前点之间的距离;
注:若特征数据差距较大,应做数据和归一化处理
数据归一化的处理方法有很多种,比如0-1标准化、Z-score标准化、Sigmoid压缩法等等
最简单的0-1标准化,公式如下:
(2) 按升序排序:按照距离递增次序排序;
(3) 确定超参数k值:选取与当前点距离最小的k个点;
(4) 统计k及k之前的类别频率: 确定前k个点所在类别的出现频率;
(5) 根据频率最高的预测类别:返回前k个点出现频率最高的类别作为当前点的预测类别。
3. 算法总结
1. 优点
- 简单好用,容易理解,精度高,理论成熟,既可以用来做分类也可以用来做回归
- 可用于数值型数据和离散型数据
- 无数据输入假定
- 适合对稀有事件进行分类
2. 缺点
- 计算复杂性高;空间复杂性高;
- 计算量太大,所以一般数值很大的时候不用这个,但是单个样本又不能太少,否则容易发生误分。
- 样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少)
- 可理解性比较差,无法给出数据的内在含义
一个简单实例:
import pandas as pd
"""
函数功能:KNN分类器参数说明:
new_data:需要预测分类的数据集
dataSet:已知分类标签的数据集(训练集)
k:k-近邻算法参数,选择距离最小的k个点
返回:
result:分类结果
"""
def classify0(inX,dataSet,k):
result = []
dist = list((((dataSet.iloc[:, 1:3] - inX) ** 2).sum(1)) ** 0.5)
dist_l = pd.DataFrame({'dist': dist, 'labels': (dataSet.iloc[:, 3])})
dr = dist_l.sort_values(by='dist')[: k]
re = dr.loc[:, 'labels'].value_counts()
result.append(re.index[0])
return result
rowdata={
'电影名称':['无问东西','后来的我们','前任3','红海行动','唐人街探案','战狼2'],
'打斗镜头':[1,5,12,108,112,115],
'接吻镜头':[101,89,97,5,9,8],
'电影类型':['爱情片','爱情片','爱情片','动作片','动作片','动作片']
}
movie_data=pd.DataFrame(rowdata) # 构建二维数组结构
new_data = [24,67]
inX = new_data
dataSet = movie_data
k = 3
test_result=classify0(inX,dataSet,k)
print(test_result)
学习来源:菊安酱的机器学习实战