算法系列——有监督学习——9.KNN

一、概述

KNN(K-Nearest Neighbor,K 近邻)算法是一种与众不同的机器学习算法,它只是机械地记住所有的数据。KNN历史悠久,早已为人所知。不过,该算法虽然简单,却可以学习复杂的边界。

KNN 既可用于分类,也可用于回归。本文以二元分类为例进行说明。KNN 算法在训练时机械地记住所有的训练数据。相较于其他算法要经历“根据训练数据计算最佳参数”的训练阶段和“使用计算出的学习参数进行预测”的预测阶段,KNN 在训练阶段不进行任何计算,直到进入预测阶段之后才进行具体的计算

在对未知数据进行分类时,KNN将计算未知数据与训练数据的距离,通过多数表决找到最邻近的k个点,然后进行分类

KNN虽然是一种简单的算法,但也适用于具有复杂边界的数据。如图是将KNN应用于具有复杂边界的数据而得到的结果。

使用KNN学习的例子:

在图中有橙色和蓝色两个标签的训练数据。在右图中,散点图中的所有点被分为两个标签,分类结果显示在了热图中。最近邻点的数量k设置为5。热图中每个坐标的颜色表示k个最近邻标签的占比。暗红色区域表示k个点的标签都是橙色的,随着比例接近1∶1,颜色会变浅,接近于蓝色。结果表明,KNN算法能够对复杂数据进行学习。

二、算法说明

KNN是一种在训练时机械地记住所有数据的简单算法。该算法使用训练数据对未知输入数据进行分类时的步骤如下。
1. 计算输入数据与训练数据之间的距离。
2. 得到距离输入数据最近的k个训练数据。
3. 对训练数据的标签进行多数表决,将结果作为分类结果。
多数表决的过程如图所示,图中设置的最近邻点k的数量为3。

最近邻点k的数量是一个超参数。在二元分类时,通常取k为奇数,这样多数表决才能决定结果是其中的哪一个。

三、示例代码

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 生成数据
X, y = make_moons(noise=0.3)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
model = KNeighborsClassifier()
model.fit(X_train, y_train)  # 训练
y_pred = model.predict(X_test)
print(accuracy_score(y_pred, y_test))  # 评估

四、详细说明

决策边界因k值而异,在KNN中,k值是一个超参数。改变k值,来看一下识别出的决策边界如何变化,如图所示,从左到右分别为k=1、k=5、k=30时的决策边界。当k=1时,图中出现了一些像飞地一样的决策边界(某类别的数据点被其他类别包围,形成局部“孤岛”‌),这说明发生了过拟合。中间的图的决策边界变得平滑,我们看不到在k=1时出现的飞地,所以k=5似乎比k=1更好。而当k=30时,背景为橙色的区域内夹杂着好多蓝色的点,这是边界过于宽松导致的错误判断。

总而言之,k值的不同会导致学到的决策边界的外观发生变化。我们需要像其他算法一样对k值进行调优,得到最佳的k值。

五、注意点

当数据量较小或维度较小时,KNN的效果很好,但是当数据量较大或维度较大时,我们就需要考虑其他方法。


首先看一下数据量较大的情况。由于要处理大量的训练数据,所以分类将变慢。这是由于在对未知数据进行分类时,KNN需要在大量的训练数据上进行近邻搜索以找到最近的点。这就意味着KNN需要同时存储大量的训练数据,也就意味着需要存储容量。为了高效地进行近邻搜索,人们经常借助于利用树结构存储训练数据的技术,但一般来说,KNN不适合处理大规模的训练数据。

KNN也无法很好地学习高维数据。KNN起作用的前提是“只要拥有的训练数据多,就能在未知数据的附近发现训练数据”这一假设。这个假设叫作渐近假设,但对于高维数据来说,这个假设不一定成立。对于高维的音频和图像数据,我们需要考虑其他方法。

虽然我们也可以使用前面提到的树结构的方式提高近邻搜索的速度,但对于大规模的数据,建议还是使用其他算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

穿梭的编织者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值