KNN(K-Nearest Neighbors,K 最近邻算法) 是一种基于实例的监督学习算法,用于分类和回归问题。
核心思想:
“物以类聚”——一个样本的类别大概率与它距离最近的样本类别相同。
KNN 不构建显式模型,而是直接利用训练样本进行预测,因此属于:
- 监督学习(Supervised Learning)
- 非参数模型(Non-parametric Model)
- 惰性学习(Lazy Learning)
给定训练集:
D={(x1,y1),(x2,y2),…,(xn,yn)}
对于新的输入样本 x:
- 计算 x 与训练集中每个样本 xi 的距离;
- 选取距离最近的 k 个样本(称为“k 近邻”);
- 分类问题:采用多数表决;
f(x)=argymaxxi∈Nk(x)∑I(yi=y)
- 回归问题:取邻居的平均值;
y^(x)=k1xi∈Nk(x)∑yi
目标:在不知道真实分布 P(Y∣X) 的情况下,用局部样本近似最优的贝叶斯分类器。
我们估计 P(Y=y∣X=x) 的思路是 “在 x 附近的邻域里统计频率”。
令 Nk(x) 表示 x 的 k 个最近邻样本集合。用指示函数 I(⋅) 计数类别 y 的出现次数:
P(Y=y∣X=x)=k1xi∈Nk(x)∑I(yi=y)
于是 KNN 分类器:
f(x)=argy∈Ymaxxi∈Nk(x)∑I(yi=y)
把 Nk(x) 看作一个“自适应体积”的邻域,其体积 Vk(x) 随数据密度自适应变化。对于某类 y:
- 类条件密度近似:p(x∣y)≈ny⋅Vk(x)#{xi∈Nk(x):yi=y}
- 先验近似:P(y)≈nny
代入贝叶斯公式后,Vk(x) 抵消,得到与上式一致的局部频率投票。
这等价于使用**均匀核(uniform kernel)**在 Nk(x) 内做核密度估计;若用距离递减的权重(见 §7),相当于换成高斯/指数等核函数。
当 n→∞,k→∞ 且 k/n→0 时,Nk(x) 会缩到 x 的无限小邻域,KNN 的经验后验 P(Y∣X=x) 收敛到真实 P(Y∣X=x),因此渐近一致;1-NN 的误差上界与贝叶斯误差成常数关系(直观理解:近邻“代表”了 x 所在类别的局部真分布)。
- 欧氏:d2(x,xi)=∑j(xj−xij)2(连续特征、各维度同尺度)
- 曼哈顿:d1(x,xi)=∑j∣xj−xij∣(对异常值更稳健)
- 闵可夫斯基:dp(x,xi)=(∑j∣xj−xij∣p)1/p(p=1,2常见)
- 余弦“距离”:dcos(x,xi)=1−∥x∥∥xi∥x⋅xi(文本/高维稀疏向量)
- 马氏距离(相关性显著时):dM(x,xi)=(x−xi)⊤Σ−1(x−xi)
若不缩放,量纲大的特征会“主导”距离。常见做法:
- 标准化:z=(x−μ)/σ
- 区间缩放:x↦(x−min)/(max−min)
注意:缩放参数必须仅用训练集拟合,避免数据泄露(在 sklearn 用 Pipeline)。
- 类别型:独热编码(one-hot)后配合欧氏/曼哈顿;或用汉明距离
- 文本:TF-IDF + 余弦相似
- 集合/二值稀疏:Jaccard 距离优先
- 缺失:先用训练集的统计量/模型插补;或用“可比较维度”的加权距离
- 异常:鲁棒缩放(如 IQR)或使用 L1 距离