K近邻

00:00
6 min Intermediate 2026/6/14

K近邻算法原理、距离度量、K值选择、KD树加速与优缺点分析。

1. K近邻算法原理

KNN(K-Nearest Neighbors)是一种懒惰学习算法,不显式训练模型,而是在预测时直接利用训练数据。

1.1 算法流程

输入: 训练集 D, 查询点 x_q, 近邻数 K
输出: x_q 的预测类别/值

1. 计算 x_q 与 D 中每个样本的距离
2. 选取距离最近的 K 个样本 N_K(x_q)
3. 分类: 多数投票 → y_q = argmax Σ I(y_i = c_k)
   回归: 取均值 → y_q = (1/K) Σ y_i

1.2 投票机制

多数投票

距离加权投票

其中

2. 距离度量

2.1 常用距离

距离公式特点
欧氏距离最常用
曼哈顿距离鲁棒性强
闵可夫斯基距离通用形式
切比雪夫距离
余弦相似度方向相似性
马氏距离考虑特征相关性

2.2 距离选择原则

  • 数值特征:欧氏距离(需标准化)
  • 稀疏特征:余弦相似度
  • 特征相关:马氏距离
  • 异常值多:曼哈顿距离

2.3 特征标准化

KNN 对特征尺度敏感,必须进行标准化:

Z-Score标准化

Min-Max归一化

3. K值选择

3.1 K值影响

K值模型复杂度过拟合风险决策边界
K=1最高最高最复杂(碎片化)
K适中适中适中合理
K=N最低最低最简单(全局多数类)

3.2 K值选择方法

  1. 交叉验证:尝试不同K值,选择验证集准确率最高的
  2. 经验法则(n为训练样本数)
  3. 奇数优先:二分类时选奇数避免平票
  4. 误差率曲线:绘制K vs 误差率,选择”肘部”

3.3 偏差-方差分析

4. KD树加速

4.1 暴力搜索复杂度

  • 训练(懒惰学习)
  • 预测(需计算与所有样本的距离)

4.2 KD树构建

KD树是一种空间划分数据结构,将 空间递归二分:

BuildKDTree(points, depth):
    if points为空: return null
    axis = depth % d          // 选择切分维度
    median = 中位数(points, axis)
    node.point = median
    node.left = BuildKDTree(points[axis < median], depth+1)
    node.right = BuildKDTree(points[axis ≥ median], depth+1)
    return node

构建复杂

4.3 KD树搜索

KNN_Search(node, target, K):
    1. 从根节点向下搜索,找到叶节点
    2. 将叶节点加入候选集
    3. 回溯:
       - 检查另一子树是否可能包含更近的点
       - 判断条件: |target[axis] - node.point[axis]| < current_max_dist
       - 如果可能,搜索另一子树
    4. 返回最近的K个点

搜索复杂

  • 平均:
  • 最坏:维数据退化

4.4 高维问题

维度 时,KD树搜索急剧下降(维度灾难):

替代方案

方法适用维度说明
KD树中低维精确搜索
Ball Tree超球体划分
LSH近似最近
HNSW索引,近似搜索
IVF + PQ倒排索引+量化

5. KNN优缺点

5.1 优点

  • 简单直观:无需训练过程
  • 参数假设数据分布无假设
  • 天然:无需扩展
  • 增量学习:新数据直接加入训练

5.2 缺点

  • 预测 每次预测
  • 内存消耗大:需存储全部训练数据
  • 维度灾难空间距离区分下降
  • 特征敏感:必须标准化
  • 不平衡数据占优

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式