「机器学习算法的数学解析与Python实现」KNN分类算法

参考资料:

数据科学中常见的9种距离度量方法,内含欧氏距离、切比雪夫距离等

KNN分类算法相对另类,不太依赖数学。

KNN分类算法:用多数表决进行分类

KNN算法中最重要的两个概念:

  • 多数表决
  • 距离

以鸢尾花样本为例,随机选取了两个特征,用不同颜色表示不同的鸢尾花类别:

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
plt.scatter(X[:, 0], X[:, 2], c=y, cmap='rainbow')

样本数据点分布图:

「机器学习算法的数学解析与Python实现」KNN分类算法

可以看出同一类的鸢尾花样本点靠的很近,而不同类别的鸢尾花则距离远一下。特征的差异形成了距离,构成了天然的边界。

当然,这也与特征值的选取有关。如何选取维度是KNN算法乃至所有机器学习算法都需要重点关注的问题,选取合适的维度可以做到事半功倍。

KNN(K-nearest Neighbor)直译就是K个最近邻,因此被称为K近邻算法,也称为最近邻算法。K的值多少,就代表使用了多少个最近邻进行投票。

KNN分类算法的原理

基本思路

KNN的“分类”是i通过多数表决来完成的,具体方法就是在待分类点的K个最近邻中,计算哪个类别的占比最多,那么待分类点就被划分为占比最多的这个类别。

KNN算法的疑惑点在于:

  1. 如何确定“K“?

  2. 如何确定”NN“?

第一个问题没有统一答案,只能根据实际情况进行调参,一般情况下K会在3~10之间。

第二个问题其实就是用什么方法度量距离,欧式距离是常用的一种方法,不同的距离度量方法被提炼成了范式,这个范式就是闵可夫斯基距离(Minkowski Distance),选择不同的距离度量方法就会衍生出不同的KNN变种。

数学解析

KNN算法本身不涉及数学,但是在查找最近邻时用到了度量距离的数学方法。

闵可夫斯基距离是对一类距离的统一定义,数学表达式如下:

\[d_P(x,y) = (\sum_{i=1}^n |x_i -y_i|^P)^{1/P} \]

通过给 \(P\) 设定不同的值,就能得到不同的距离表达式。

当 \(P=1\) 时,称为曼哈顿距离,表达式如下:

\[d(x,y) = \sum_{i=1}^n |x_i -y_i| \]

当 \(P=2\) 时,称为欧式距离,表达式如下:

\[d_2(x,y) = \sqrt{\sum_{i=1}^n (x_i -y_i)^2} \]

选择什么样的距离度量方法需要根据实际情况而定。

具体步骤

KNN分类算法信息表

「机器学习算法的数学解析与Python实现」KNN分类算法

KNN分类算法的实现思路分三步:

  1. 找K个最近邻;
  2. 统计最近邻的类别占比;
  3. 选取占比最多的类别作为待分类样本的类别。

在Python中使用KNN分类算法

在sklearn中,最近邻模型算法族都在neighbors类库中。具有代表性的几个类如下:

  • KNeighborsClassifier类:最经典的KNN分类算法。
  • KNeighborsRegressor类:利用KNN算法解决回归问题。
  • RadiusNeighborsClassifier:基于固定半径来查找最近邻的分类算法。
  • NearestNeighbors类:基于无监督学习实现KNN算法。
  • KDTree类:无监督学习下基于KDTree来查找最近邻的分类算法。
  • BallTree类:无监督学习下基于BallTree来查找最近邻的分类算法。

用法如下:

# 导入KNN分类算法
from sklearn.neighbors import KNeighborsClassifier

# 载入鸢尾花数据集
X, y = load_iris(return_X_y=True)

# 训练模型
clf  = KNeighborsClassifier().fit(X, y)

# 使用模型进行分类预测
clf.predict(X)

预测结果如下:

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

使用默认的性能评估器评分:

clf.score(X, y)

性能得分如下:

0.9666666666666667

KNN分类算法的使用场景

KNN算法的准确度受样本的类别分布影响明显,如果数据集中某类样本数量明显占多数,这将导致多数表决“不公平”,待预测的样本很有可能会被误划入该类。同时,KNN算法每次均需要计算所有点之间的距离,样本数量大时,需要耗费大量内存。

KNN分类算法的特点

「机器学习算法的数学解析与Python实现」KNN分类算法

算法使用案例

OCR(Optical Character Recognition,光学字符识别),在深度学习兴起之前,一般是通过KNN和SVM实现的。

用KNN实现OCR主要分为三步:

  1. 确定文字所在的位置区域;
  2. 提取特征;
  3. 通过KNN,判断所提取的相关特征属于哪个字符。
上一篇:『无为则无心』Python序列 — 19、Python列表的其他操作(切片和遍历)


下一篇:kNN算法