统计学习方法——K近邻法【k-NN】(二)

k k k近邻的实现—— k d kd kd

k k k近邻的主要工作量是:找到到样本最近的 k k k个点。最简单的无疑是线性扫描,但数据量太大时非常耗时不可行,因此提出了 k d kd kd树。

k d kd kd

构造 k d kd kd
  • 特点
    • 一种对 k k k维空间中的实例点进行存储以便进行快速检索的树形结构
    • 是二叉树
    • 构造 k d kd kd树相当于不断用垂直于坐标轴的超平面将 k k k维空间划分
    • 树的每个结点对应于一个 k k k维超矩阵区域
  • 构造方法
    输入维 k k k维空间数据集 T = { x 1 , x 2 , ⋯   , x N } T = \left\{ {{x_1},{x_2}, \cdots ,{x_N}} \right\} T={x1,x2,,xN},其中 x i = ( x i ( 1 ) , x i ( 2 ) , ⋯   , x i ( k ) ) T {x_i} = {\left( {x_i^{\left( 1 \right)},x_i^{\left( 2 \right)}, \cdots ,x_i^{\left( k \right)}} \right)^T} xi=(xi(1),xi(2),,xi(k))T
    • 构造根节点,根节点对应于包含 k k k维空间所有实例点的超矩阵区域
    • 选择 x ( 1 ) {x^{\left( 1 \right)}} x(1)为坐标轴,以 T T T中所有实例的 x ( 1 ) {x^{\left( 1 \right)}} x(1)坐标的中位数为切分点,通过切分点并垂直于 x ( 1 ) {x^{\left( 1 \right)}} x(1)坐标轴的超平面将根节点的矩形区域分为两个子区域。
    • 由根节点生成深度为 1 1 1的左、右子节点,左子节点对应坐标 x ( 1 ) {x^{\left( 1 \right)}} x(1)小于切分点的子区域,右子节点则是大于的。
    • 重复:对深度为 j j j的结点,选择 x ( l ) {x^{\left( l \right)}} x(l)为切分的坐标轴, l = j (   m o d   k ) + 1 l = j\left( {\bmod k} \right) + 1 l=j(modk)+1
    • 直到两个区域都没有实例为止,形成 k d kd kd树的区域划分。

注:通过中位数分割得到的 k d kd kd树是平衡的,但平衡 k d kd kd树的搜索效率未必是最优的。

k d kd kd树的搜索方法

这里我们以最近邻为例,介绍搜索算法。

  • 输入:构造好的 k d kd kd树,目标点 x x x
  • 输出: x x x的最近邻
  • 搜索
    • k d kd kd树中找到包含目标点 x x x的叶节点。
      从根节点出发,若目标点 x x x当前维德坐标小于切分点则向左移动,否则向右,直到叶子节点为止。
    • 从此结点为“当前最近点”,向上回退,并执行
      • 如果该节点该结点比当前最近点离目标更近,则以此结点作为“当前最近点”
      • 当前最近点必然存在于该节点的一个子节点对应的区域,检查另一子节点的区域是否与(以目标点为球心,目标点到当前最近点距离为半径的超球体)相交,若相交则移动到另一个子节点,继续递归,不相交则向上回退。
    • 回退到根节点结束。
      k d kd kd树搜索的平均计算法复杂度为 O ( log ⁡ N ) O\left( {\log N} \right) O(logN) N N N为训练实例数。
      k d kd kd树更适合训练实例远大于空间维数时的 k k k近邻搜索。
简单示例

如图所示的 k d kd kd树,求S的最近邻(这里考虑欧式距离)。
实例
其实将其转化为树的形式为:
树形结构
整个搜索过程对比两个图,应该是:

  1. 从根节点开始,向下找到包含 S S S的结点 D D D,此时最近点也为 D D D
  2. D D D向上搜索, B B B显然比 D D D S S S
  3. 搜索 B B B的另一个子节点, F F F并不与此时C的圆相交,显然也不是
  4. 向上回退到 A A A A A A不能成为最近点
  5. 搜索 A A A的另外一边,发现与圆相交,说明在另一边存在最近点
  6. 在另一边搜索会找到点 E E E,也就是真正的最近点
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值