文章

Python 首批细教程 · 06B:用一个小例子彻底看懂 kNN 怎么分类

#275 · 2026-05-13 · Python 教程拆解

对应原仓库Day81-90/82.k最近邻分类.md

已提供可运行示例/tutorial-assets/python-100-days/06b-knn-movie-demo/(站点源码路径:blog-src/static/tutorial-assets/python-100-days/06b-knn-movie-demo/

原仓库里这一篇把概念说得很清楚:找最近的 k 个邻居,然后投票。

这一篇我们把它缩成一个最小可运行例子。

训练集

假设我们有两类电影:

  • 爱情片:动作少、吻戏多
  • 动作片:动作多、吻戏少

代码

from sklearn.neighbors import KNeighborsClassifier


X = [
    [2, 9],
    [1, 8],
    [8, 1],
    [9, 2],
]
y = ["romance", "romance", "action", "action"]

model = KNeighborsClassifier(n_neighbors=3)
model.fit(X, y)

sample = [[3, 7], [8, 2]]
pred = model.predict(sample)
print(pred.tolist())

安装:

pip install scikit-learn

运行后你会看到一条更偏爱情、一条更偏动作的预测结果。

这里到底发生了什么

对于 sample = [3, 7]

  1. 它会和训练集每个点计算距离;
  2. 选出最近的 3 个点;
  3. 看这 3 个点里哪个类别更多;
  4. 多数投票就是预测结果。

这就是原仓库里讲的 kNN 核心机制。

k 值为什么重要

原仓库特别强调了一点:k 太小容易过拟合,太大又会被远处样本干扰。

你自己可以试:

for k in [1, 3]:
    model = KNeighborsClassifier(n_neighbors=k)
    model.fit(X, y)
    print(k, model.predict([[4, 6]]).tolist())

进阶任务

  1. 自己再补两条训练数据。
  2. 把类别改成 comedy / horror 试试。
  3. 查询 train_test_split,把样本拆成训练集 / 测试集。

常见坑

  • k 大于样本数量。
  • 特征量纲差太大却不做缩放。
  • 以为“训练”很复杂,其实 kNN 恰恰是惰性学习。