Fork me on GitHub

机器学习实战-4-KNN算法总结

机器学习实战-4-KNN算法总结

在前两篇文章机器学习实战-2-KNN机器学习实战-3-基于KNN的约会网站配对实现中结合实际案例详细讲解了KNN算法的知识,主要包含:

  • 算法的原理及概述
  • 算法的主要步骤
  • 图解KNN算法
  • 如何建立KNN分类
  • 电影分类和约会网站配对案例

还有其他的内容,比如KNN算法中使用的欧式距离涉及到的机器学习中的度量问题、jupyter notebook中如何使用KNN算法等。本文主要是对KNN算法做一个总结。

算法理论

KNN算法
功能 分类(核心),回归
算法类型 有监督学习-惰性学习
数据输入 特征矩阵至少包含k个训练样本,数据标签
特征空间中的各个特征的量纲需要统一,如果不统一,需要做归一化处理
自定义的的超参数k
数据输出 KNN分类:输出的是标签中的某个类别
KNN回归:输出的是对象的属性值,该值是距离输入的数据最近的k个训练样本标签的均值

算法原理

  • 计算已知类别数据集中的点与当前点之间的距离;
  • 按照距离递增次序排序
  • 选取与当前点距离最小k个点;
  • 确定前k个点所在类别的出现频率;
  • 返回前k个点所出现频率最高的类别作为当前点的预测分类。

KNN分类器

利用Python创建一个KNN分类器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np

"""
函数说明:KNN算法分类
函数参数:
inX 用于分类的数据集(测试集)
dataSet 用于训练的数据(训练集)
labels 分类标签
k 算法参数,选择距离最近的k个点
修改时间:
2021-02-28
"""
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] # 文件行数,即大小
diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet # np.tile表示在两个方向上的重复次数,达到和原始数据相同的shape,以便能够相减
sqDiffMat = diffMat ** 2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances ** 0.5 # 以上3步:距离相减再平方,再求和,再开根号
# 获取到的是索引值!!!
sortedDistIndices = distances.argsort() # 全部距离从小到大排序后的索引值
classCount = {} # 存储类别次数的字典
for i in range(k):
voteIlabel = labels[sortedDistIndices[i]] # 根绝每个索引,取出对应的前k个元素的类别
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 # 计算类别次数;get方法返回指定键的值,否则返回默认值


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

​ 根据电影分类问题写出的简洁版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import pandas as pd

"""
函数功能:KNN分类器

参数说明:
inX:待预测分类的数据
dataSet:原数据集,训练集
k:k-近邻算法中的超参数k

返回值:
分类结果
修改时间:
2021-02-28
"""

def classify0(inX, dataSet,k):
result = []

# 1、求新数据和每个原数据的距离
dist = list(((data.iloc[:6,1:3] - new_data) ** 2).sum(1) ** 0.5)
# 2、将求出的距离和电影标签放在一起
dist_labels = pd.DataFrame({"dist":dist,"labels":data["电影类型"].tolist()})
# 3、根据距离升序排列,取出前k个
dist_sorted = dist_labels.sort_values(by="dist")[:k]
# 4、排序之后取出标签,并统计频数
res = dist_sorted.loc[:,"labels"].value_counts()
result.append(res.index[0])

return result

算法优点

  • 简单好用,容易理解,理论成熟。
  • 算法既可以用来分类,也可以用来做回归
  • 算法既可以用来处理数值型数据(电影类别判断案例),也可以处理离散型数据(海伦约会案例)
  • 无数据输入假定,直接对数据进行训练
  • 对异常值不敏感

算法缺点

  • 计算复杂性高,空间复杂度高,从而导致计算量大
  • 如果数值多不适合,计算量过大
  • 可解释性差,不能给出数据的内在含义
  • 样本不平衡问题:有些类别的样本多,有些类别的样本数量较少

参考资料

1、《机器学习实战》一书

2、李航老师:《统计学习方法》

3、机器学习实战教程(一):K-近邻算法(史诗级干货长文)

本文标题:机器学习实战-4-KNN算法总结

发布时间:2021年02月28日 - 18:02

原始链接:http://www.renpeter.cn/2021/02/28/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%AE%9E%E6%88%98-4-KNN%E7%AE%97%E6%B3%95%E6%80%BB%E7%BB%93.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea