参数设置
查询点在平面上自动移动,实时显示到 k 最近邻的连线、包含圆和多数投票类的颜色。数据由种子42的LCG确定性生成(每类15个点,共45个点)。距离采用欧几里得距离。
学习数据与决策边界
红色=类0/蓝色=类1/绿色=类2/白线=到 k 最近邻的连线/虚线圆=到第 k 个最近邻的距离/实心圆=查询点(多数投票类的颜色)
理论与主要公式
k最近邻法是一种延迟学习算法,记忆学习数据,查询时选择距离查询点$\mathbf{x}$最近的k个学习点,通过多数投票预测类。
二维欧几里得距离。学习点$\mathbf{x}_i = (x_{i1}, x_{i2})$和查询点$\mathbf{x} = (x_1, x_2)$:
$$d(\mathbf{x},\mathbf{x}_i) = \sqrt{(x_1 - x_{i1})^2 + (x_2 - x_{i2})^2}$$
预测类。$\mathcal{N}_k(\mathbf{x})$为查询点的k最近邻集合,$y_i$为学习点$\mathbf{x}_i$的类标签:
$$\hat{y}(\mathbf{x}) = \arg\max_{c}\;\sum_{\mathbf{x}_i \in \mathcal{N}_k(\mathbf{x})}\mathbb{1}[y_i = c]$$
LOO交叉验证精度(留一法)。$\hat{y}^{(-i)}$为排除$\mathbf{x}_i$后训练的分类器的预测:
$$\text{Acc}_\text{LOO} = \frac{1}{N}\sum_{i=1}^{N}\mathbb{1}[\hat{y}^{(-i)}(\mathbf{x}_i) = y_i]$$
当多数投票平局时,比较各候选类到k最近邻的平均距离,选择距离较小的类作为预测类。
k 最近邻法(k-NN)2D 分类模拟器简介
🙋
我开始学习机器学习,听说k最近邻法是最简单的,但也很有效。这是真的吗?
🎓
完全正确。简单来说,k-NN是一种"不学习模型"的算法。它只记住学习数据,当新数据来临时,找出最近的k个点,然后通过多数投票决定类别。就这么简单。在上面的模拟器中,您能看到红、蓝、绿的点吧?黑色的×是查询点,当k=5时,它会查找最近的5个点进行多数投票。
🙋
当我拖动k值滑块时,背景的着色方式完全改变了。这是什么?
🎓
那就是"决策边界"。我们对平面上的每个点计算"如果这里是查询点,会预测哪个类",然后用该类的颜色轻轻着色背景。k=1时,边界会很锯齿状,因为它被单个异常点拖拽。当k增加到11或21时,边界会变得平滑,但会忽略一些细微的结构。
🎓
都不是。正确的做法是"根据数据选择k"。看看LOO交叉验证精度卡片。这是将学习数据中的一个点排除,用其余部分进行预测,对所有点重复此过程的正确率。对于种子42的数据,k=5大约能达到90%。实际工作中,我们会尝试k=1、3、5等,选择精度最高的那个。为了避免投票平局,习惯上选择奇数。
🙋
我把"学习数据分散 σ"提高到3.0,结果类别混在一起,精度大幅下降。
🎓
这是k-NN的弱点,也是其强点。当数据分布清晰时,它能给出高精度,但当类别重叠时,无论选什么k都有限。实际工作中,"调整特征来分离类别"比"改进分类器"更重要。k-NN之所以是强大的基准线,正是因为它能直观地反映特征设计的好坏。
常见问题
不必须。距离度量的选择取决于应用场景。本模拟器使用欧几里得距离(L2范数),因为它在2D中直观易懂,但实际工作中还有曼哈顿距离(L1)、余弦相似度、马氏距离等。特别是在文本分类等高维稀疏向量场景中,余弦相似度很常见;当特征尺度差异很大时,马氏距离是首选。
预测时的计算成本。每次预测都要计算与所有学习点的距离,对N个点的数据需要O(N)的时间。数据量很大时预测会很慢,不适合实时应用。实际工作中使用kd树、球树等空间数据结构,或近似最近邻搜索库(如FAISS、Annoy)来加速。
绝对必要。k-NN基于距离,如果特征尺度差异大(如年收入vs年龄),大尺度特征会压倒小尺度特征。必须进行标准化(均值0、方差1)或Min-Max归一化。本模拟器所有特征都是同一尺度的2D数据,所以不需要缩放,但实际应用中这是必须的。
当k接近学习数据数量时,任何查询都返回"所有数据的多数类"。决策边界消失,少数类永远不被预测。反之k=1时,对学习数据的拟合完全,容易过学习。现实的解决方案是边看LOO精度卡片边选择合适的k。
实际应用
推荐系统:在电影或商品推荐中,将用户和商品表示为多维向量,用k-NN查找"相似用户"或"相似商品"。Amazon的"购买此商品的人还看了…"和Netflix的协同过滤背后都有这种思想。大规模系统中使用近似最近邻库在几亿个向量中瞬间找到k个邻近向量。
异常检测:在制造、传感器或网络流量数据中,使用"到k个最近邻的平均距离"作为异常得分。在正常数据密集分布的空间中,若k个最近邻都很远,则判断为"孤立 = 异常"。模拟器的"查询点到k最近邻的平均距离"卡片正是这个指标。
图像分类与OCR基础:在手写数字识别(MNIST)等经典基准中,k-NN在深度学习前是强基准。将原始像素值视为784维向量,用k-NN分类只需3%左右的误分类率。现在它仍被用作模型合理性验证的"下界"。
地理信息与空间搜索:地图应用中的"离我最近的5家咖啡"就是k最近邻搜索。将经纬度作为2D坐标,距离用球面距离表示,用R树等空间索引加速的k-NN是许多地理服务的基础。
常见误区与注意事项
最常见的误解是"k-NN不需要学习很简单"。虽然学习阶段只是"保存数据",但预测阶段很重,特征设计决定了一切。在模拟器中把σ增加到3.0,类别混在一起,无论k多少LOO精度都大幅下降。这说明"特征空间中类别分离不充分",k-NN无法解决。看似学习不需要,但特征工程需要人的智慧。
次常见的误解是"k越大精度越高"。k=1确实容易过学习,但持续增加k会遇到"少数类被多数类吞没"的反向问题。在模拟器中从k=1调整到k=25,边看LOO精度边变化,会发现最优k在中间,且随数据分布改变。k是需要用交叉验证系统选择的超参数,而不是"越大越好"或"越小越好"。
最后的危险误区是"LOO精度高就能保证实际运行也高精度"。LOO交叉验证暗含假设:训练数据分布等于实际数据分布。实际上常发生"数据漂移"——收集时间、传感器等因素导致分布变化,LOO精度90%却实际只有70%。模拟器的LOO精度是理想条件,实务中还需用hold-out验证或时间序列交叉验证再验证一次。
具体计算示例
训练数据集:A类(2,3)(4,5)(6,2)、B类(8,8)(9,7)。查询点(5,4),k=3时计算欧几里得距离:点(4,5)距离√2≈1.41、点(6,2)距离√5≈2.24、点(8,8)距离√13≈3.61。最近3点为A、A、B,多数投票预测为A类。LOO精度对全部5个数据点交叉验证,例如4/5正确时精度80%