K-NEAREST NEIGHBORS
学完本节课,你将能够:
- 区分“特征”和“标签”
- 理解寻找邻居并投票的过程
- 用距离表示样本的相似程度
- 理解K值为什么会影响结果
问题引入:这朵新花是什么品种?
植物学家提供历史数据,由你完成一次新品种判断。
一份来自植物学家的研究任务
从已知样本出发,判断一朵新花。
外观相近,却有三个品种
研究对象可以分为山鸢尾、变色鸢尾和维吉尼亚鸢尾。品种差异与花萼、花瓣的长宽密切相关。
测量数据 + 正确品种
植物学家测量每朵花的四项数据,再由专家确认真实品种,建立了一份可供分析的历史样本。
判断一朵未知的新花
新花的四项测量已经完成,但品种仍是未知。请结合历史样本,判断它最可能属于哪一个品种。
已知特征 → 预测标签NEW SAMPLE首先看看这朵等待判断的新花,植物学家已经为我们提供了哪些测量数据。
| 特征 | 测量结果 |
|---|---|
| 花萼长度 | 6.0 cm |
| 花萼宽度 | 2.9 cm |
| 花瓣长度 | 5.0 cm |
| 花瓣宽度 | 1.7 cm |
| 品种 | ? |
只有测量数据,怎样判断这朵新花的品种?
查看直觉思路
- 在历史数据中找一些和它长得相似的花;
- 查看这些相似花朵已经确认的品种;
- 哪个品种出现得最多,就把新花暂时判断为哪个品种。
这个从历史样本中寻找“邻居”的直觉方法,就是KNN算法的基本思想。
问题分析:特征、标签和分类
什么是特征?
花萼长度、花萼宽度、花瓣长度和花瓣宽度,都是描述一朵花的可测量信息。在机器学习中,这些用来描述对象的信息叫作特征。
特征,就是我们用来认识和区分一个对象的信息。
| 判断对象 | 可以采集的特征 |
|---|---|
| 鸢尾花 | 花瓣长度、花瓣宽度 |
| 一套房子 | 面积、楼层、位置、房龄 |
| 一位用户 | 年龄、消费次数、浏览偏好 |
| 一封邮件 | 发件人、关键词、链接数量 |
并不是特征越多越好。真正有帮助的,是能够体现不同类别差异的特征。
什么是标签?
历史数据中的每朵花都已经由专家鉴定了品种。“山鸢尾”“变色鸢尾”“维吉尼亚鸢尾”就是这些数据的标签。
标签,就是历史数据中已经确认的正确答案。
| 花瓣长度 | 花瓣宽度 | 品种标签 |
|---|---|---|
| 1.4 | 0.2 | 山鸢尾 |
| 4.5 | 1.5 | 变色鸢尾 |
| 5.7 | 2.1 | 维吉尼亚鸢尾 |
新花只有特征、没有标签。我们的任务,是根据历史数据预测它的标签,这类问题叫作分类问题。
解题思路:物以类聚,人以群分
同一个品种的花,在花瓣长度和宽度上往往比较接近:山鸢尾普遍短而窄,变色鸢尾大小居中,维吉尼亚鸢尾通常更长、更宽。
- 把新花放进历史数据中
- 找到与它最相似的几朵花
- 查看这些花的品种
- 让邻居进行投票
- 用票数最多的品种作为预测
KNN就是找到离新样本最近的K个历史样本,让它们投票决定新样本的类别。
如何找到最相似的花?
把“看起来很像”的直觉,变成计算机能够比较的数字。
直观地说,我们会把新花与历史花朵逐项比较:花瓣长度是否接近、花瓣宽度是否接近,花萼长度和宽度又相差多少。四项数据越接近,两朵花就越相似。
但计算机不能只凭“看起来像”作判断。我们需要把相似程度变成一个可以计算、排序的数字,这个数字就是距离:距离越小,样本越相似。
比较一个数字的差值
只看花瓣长度时,5.0 cm 与 5.1 cm 相差 0.1 cm。差值越小,就越相似。
| 5.0 − 5.1 | = 0.1合并两个方向的差异
同时比较长度和宽度时,把两个差值分别平方、相加,再开平方,得到平面上的直线距离。
√(长度差² + 宽度差²)扩展为空间向量距离
使用四项特征时方法不变:将每一维的差异合并,得到两个特征向量之间的距离。
√(差₁² + … + 差₄²)从一维到多维,核心始终相同:把各项特征的差异合并成一个距离,距离越小,就代表越相似。
先把每朵花放到二维坐标图上
为了便于理解,暂时只选择两个特征:横轴是花瓣长度,纵轴是花瓣宽度。每朵花都可以表示为一个点,例如历史花是 (4.5, 1.5),新花是 (5.0, 1.7)。
图上的两个点越近,说明两朵花在这两个特征上越相似。
什么是向量?
看到“向量”不必紧张。这里可以把它理解为“按照固定顺序排列的一组数字”。
特征向量,就是用一组有固定顺序的数字来描述一个对象。
如何计算距离?
A点为 (1, 1),B点为 (4, 5)。横向相差3,纵向相差4,根据勾股定理,两点直线距离为5。
距离只有0.14,说明两朵花非常相似。使用四个特征时方法不变:分别计算四项差值、平方、相加,最后开平方。
计算结果:让最近的5朵花投票
计算机会求出新花与每一朵历史花的距离,然后从近到远排序。
| 排名 | 花瓣长度 | 花瓣宽度 | 距离 | 历史标签 |
|---|---|---|---|---|
| 1 | 5.1 | 1.6 | 0.14 | 变色鸢尾 |
| 2 | 4.8 | 1.8 | 0.22 | 变色鸢尾 |
| 3 | 4.9 | 1.5 | 0.22 | 变色鸢尾 |
| 4 | 4.5 | 1.5 | 0.54 | 变色鸢尾 |
| 5 | 5.5 | 1.9 | 0.54 | 维吉尼亚鸢尾 |
| 6 | 5.7 | 2.1 | 0.81 | 维吉尼亚鸢尾 |
变色鸢尾 4票维吉尼亚鸢尾 1票山鸢尾 0票
答案不是凭空产生的:先计算距离,再选出最近的5朵花,最后统计它们的已知标签。
K值为什么会影响结果?
K代表参加投票的邻居数量。我们可以寻找最近的3朵、5朵或7朵花。参加投票的邻居发生变化,最终结果也可能改变。
| K值 | 邻居投票结果 | 预测结果 |
|---|---|---|
| K=3 | 3朵变色,0朵维吉尼亚 | 变色鸢尾 |
| K=5 | 4朵变色,1朵维吉尼亚 | 变色鸢尾 |
| K=7 | 4朵变色,3朵维吉尼亚 | 变色鸢尾 |
- K太小,容易受到个别异常数据影响;
- K太大,可能把较远、不相似的数据也算进来;
- 实际工程会尝试多个K值并比较效果;
- 二分类经常选择奇数,减少平票可能。
K不是凭感觉永久确定的,而是需要通过数据实验不断验证。
改变 K,观察投票结果
当前选择最近的 5 朵花
K值改变 → 邻居改变 → 票数改变 → 结果可能改变
KNN的完整工作过程
- 01输入新花的特征
- 02计算与每朵历史花的距离
- 03按照距离从近到远排序
- 04选择最近的K朵花
- 05统计邻居的品种
- 06用票数最多的品种作为预测
KNN认为,彼此相似的数据,通常更可能属于同一类别。
把完整过程写成 Python 代码
理解算法步骤后,我们可以直接使用 sklearn 中的KNN模型完成相同过程。下面的示例使用完整鸢尾花数据训练模型,再预测课程中的新花 [6.0, 2.9, 5.0, 1.7]。
用代码完成一次KNN分类
from sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerfrom sklearn.neighbors import KNeighborsClassifieriris = load_iris()X, y = iris.data, iris.targetX_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)scaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)model = KNeighborsClassifier(n_neighbors=5)model.fit(X_train, y_train)accuracy = model.score(X_test, y_test)new_flower = [[6.0, 2.9, 5.0, 1.7]]new_flower = scaler.transform(new_flower)prediction = model.predict(new_flower)print(iris.target_names[prediction[0]])逐行理解代码
- 01
从 sklearn 内置数据集中导入鸢尾花数据加载器。
- 02
导入数据拆分工具,用来划分训练集和测试集。
- 03
导入标准化工具,避免不同特征的数值范围干扰距离。
- 04
导入 sklearn 提供的 KNN 分类模型。
- 05
加载完整鸢尾花数据,包括四项特征、品种标签和字段说明。
- 06
X 保存花萼与花瓣的四项特征,y 保存每朵花的品种标签。
- 07
开始拆分数据:模型用训练集寻找邻居,用测试集检查预测效果。
- 08
取20%作为测试集;固定随机种子,并保持三个品种的比例。
- 09
完成训练集和测试集的拆分。
- 10
创建标准化器,让四项特征处于可比较的数值尺度。
- 11
从训练数据学习标准化规则,并转换训练集。
- 12
使用同一套规则转换测试集,不能重新学习一次。
- 13
创建KNN模型,并规定每次参考最近的5个邻居。
- 14
把训练特征和正确标签交给模型;KNN会保留这些历史样本。
- 15
让模型预测测试集,并计算分类准确率。
- 16
输入课程中的新花,四个数字的顺序必须与训练数据一致。
- 17
用训练阶段得到的标准化规则处理新花。
- 18
寻找新花最近的5个训练样本,通过投票得到品种编号。
- 19
把品种编号转换为名称并输出预测结果。
KNN到底“学习”了什么?
KNN与一些会提前总结规律的算法不同。它保留历史数据,遇到新问题时,再寻找最近的邻居。
新同学选择社团
一位新同学喜欢篮球、跑步和户外活动。找到兴趣最相似的5名老同学,如果其中4人加入体育社,就可以合理猜测他也可能选择体育社。
| 新同学的兴趣 | 特征 |
|---|---|
| 老同学参加的社团 | 标签 |
| 兴趣相似程度 | 距离 |
| 最相似的几位老同学 | K个邻居 |
| 邻居选择最多的社团 | 预测结果 |
KNN不是凭空猜测,而是根据历史上与新对象最相似的数据作出判断。
KNN可以用在哪里?
水果分类
根据重量、大小、颜色和甜度判断水果种类。
手写数字识别
将图片转换成像素数据,寻找最相似的历史数字。
用户分级
根据浏览、购买和消费金额判断用户等级。
内容推荐
寻找兴趣相似的用户或内容,辅助完成推荐。
疾病辅助判断
根据年龄、体温、心率和检查指标寻找相似案例。算法结果只能作为辅助,不能代替医生诊断。
KNN的优点和局限
简单、直观、低门槛
- 思想直观,容易理解
- 不需要复杂训练过程
- 可用于分类和数值预测
- 适合小规模、结构清晰的数据
距离并不总是可靠
- 数据多时,每次预测计算量大
- 无关特征可能干扰判断
- 不同单位和范围会影响距离
- K值需要通过实验选择
- 类别不均衡时多数类易占优势
年龄通常是几十,年收入可能是几十万。直接计算距离时,收入会产生过大的影响。实际工程通常会先对不同特征做标准化处理;具体方法将在后续课程中展开。
LESSON SUMMARY
你已经理解了KNN
- 特征是描述对象的信息,标签是历史数据中的正确答案。
- KNN通过寻找最近的历史样本预测新样本。
- “最近”通常通过特征向量之间的距离判断。
- 最近的K个邻居通过投票决定分类结果。
- K值、特征选择和数据处理都会影响预测效果。
KNN是一种根据样本之间的距离,找到最近的K个历史样本,再通过邻居投票完成分类的机器学习算法。
课后思考
假设我们希望判断一位新用户是否会购买某项产品:
- 你准备采集哪些特征?
- 历史数据的标签是什么?
- 什么样的用户可以算作“相似用户”?
- K取3、5或7时,结果是否可能不同?
查看思路
可以从用户的浏览、收藏、购买频率和消费金额出发;标签可以是“购买”或“未购买”。相似用户需要在选定特征上距离较近,而不同K值确实可能带来不同投票结果。