第三章总结 K近邻法及kd树

本文 参考自李航博士的《统计学习方法》 为自我理解的简化版本

3.1 K近邻算法

给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。

y=argmaxxiNk(x)I(yi=ci) y = a r g max ∑ x i ∈ N k ( x ) I ( y i = c i )

I为指示函数,即当 yi=ci y i = c i I I 为1,否则 I 为 0。

3.2 K近邻模型

3.2.1 距离度量

特征空间中两个实例点的距离是两个实例点相似程度的反映。使用的距离一般是欧式距离,也可以是 Lp L p 距离 或 Minkowski M i n k o w s k i 距离 和 哈曼顿距离。

3.2.2 K值的选择

在应用中,k值一般取一个比较小的数值。通常采用交叉验证法来选取最优的k值。

3.2.3 分类决策规则

k近邻法中的分类决策规则往往是多数表决,误分类概率

P(Yf(X))=1P(Y=f(X)) P ( Y ≠ f ( X ) ) = 1 − P ( Y = f ( X ) )

对给定的实例 xX x ∈ X ,其最近邻的k个训练实例点构成的集合 Nk(x) N k ( x ) .如果涵盖 Nk(x) N k ( x ) 的区域的类别为 cj c j ,那么误分类率

1kxiNK(x)I(yici)=11kxiNK(x)I(yi=ci) 1 k ∑ x i ∈ N K ( x ) I ( y i ≠ c i ) = 1 − 1 k ∑ x i ∈ N K ( x ) I ( y i = c i )

要使误分类率最小即经验风险最小,就要使 xiNK(x)I(yi=ci) ∑ x i ∈ N K ( x ) I ( y i = c i ) 最大,所以多数表决规则等价于经验风险最小化。

3.3 K近邻法的实现:kd树

为什么要使引入kd树:

k近邻法最简单的实现就是线性扫描计算输入实例点与每个训练实例的距离,训练集很大时,这种方法是不可取的。
为了提高k近邻搜索的效率,可以使用像kd树这样的特殊结构存储训练数据,以减少计算距离的次数。

3.2.1 kd树 :构造
算法:构造kd树(createKDTree)

来自百度

输入: k k 维空间数据集 Data set s e t 和其所在的空间 Range R a n g e
输出: kd k d tree t r e e

  1. 如果数据集 Data D a t a set s e t 为空,则返回空的 kd k d tree t r e e

  2. 调用节点生成程序:
    (1)确定split域:对于所有描述子数据(特征矢量),统计它们在每个维上的数据方差。
    以SURF特征为例,描述子为64维,可计算64个方差。
    挑选出最大值,对应的维就是split域的值。
    数据方差大表明沿该坐标轴方向上的数据分散得比较开,在这个方向上进行数据分割有较好的分辨率;
    (2)确定Node-data域:
    数据点集Data-set按其第split域的值排序。
    位于正中间(中位数)的那个数据点被选为Node-data。
    此时新的Data-set’ = Data-set \ Node-data(除去其中Node-data这一点)。

  3. dataleft = { d属于 Data-set’ && d [split] ≤ Node - data [split] }
    Left_Range = { Range && dataleft }
    dataright = { d属于 Data-set’ && d [split] > Node - data [split] }
    Right_Range = { Range && dataright }

  4. left = 由(dataleft,Left_Range)建立的k-d tree,
    即递归调用createKDTree(dataleft,Left_Range),并设置left的parent域为Kd;
    right = 由(dataright,Right_Range)建立的k-d tree,
    即调用createKDTree(dataright,Right_Range),并设置right的parent域为Kd。

举个栗子

假设有6个二维数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},数据点位于二维空间内(如图1中黑点所示)。
这里写图片描述
由于此例简单,数据维度只有2维,所以可以简单地给x,y两个方向轴编号为0,1,也即split={0,1}。
(1)确定split域的首先该取的值。分别计算x,y方向上数据的方差得知x方向上的方差最大,所以split域值首先取0,也就是x轴方向;
(2)确定Node-data的域值。根据x轴方向的值2,5,9,4,8,7排序选出中值为7,所以Node-data = (7,2)。这样,该节点的分割超平面就是通过(7,2)并垂直于split = 0(x轴)的直线x = 7;
(3)确定左子空间和右子空间。分割超平面x = 7将整个空间分为两部分,如图2所示。x < = 7的部分为左子空间,包含3个节点{(2,3),(5,4),(4,7)};另一部分为右子空间,包含2个节点{(9,6),(8,1)}。

如算法所述,k-d树的构建是一个递归的过程。然后对左子空间和右子空间内的数据重复根节点的过程就可以得到下一级子节点(5,4)和(9,6)(也就是左右子空间的’根’节点),同时将空间和数据集进一步细分。如此反复直到空间中只包含一个数据点,如图1所示。最后生成的k-d树如图3所示。

3.2.1 kd树 :搜索
算法:kd 树最近邻搜索

来自李航博士的《统计学习方法》

输入: 已构造的kd树;目标点;
输出: x x <script type="math/tex" id="MathJax-Element-1360">x</script> 的最近邻。

(1) 在kd树中找出包含目标点的叶结点:从根结点出发,递归的向下访问kd树。
若目标点当前维的坐标值小于切分点的坐标值,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止;

(相当于二分查找)

(2) 以此叶结点为“当前最近点”;

(3) 递归的向上回退,在每个结点进行以下操作:

  (a) 如果该结点保存的实例点比当前最近点距目标点更近,则以该实例点为“当前最近点”;

  (b) 当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一个子结点对应的区域是否有更近的点。具体的,检查另一个子结点对应的区域是否与以目标点为球心、以目标点与“当前最近点”间的距离为半径的超球体相交。如果相交,可能在另一个子结点对应的区域内存在距离目标更近的点,移动到另一个子结点。接着,递归的进行最近邻搜索。如果不相交,向上回退。

(4) 当回退到根结点时,搜索结束。最后的“当前最近点”即为的最近邻点。

举个栗子

以先前构建好的kd树为例,查找目标点(3,4.5)的最近邻点。同样先进行二叉查找,先从(7,2)查找到(5,4)节点,在进行查找时是由y = 4为分割超平面的,由于查找点为y值为4.5,因此进入右子空间查找到(4,7),形成搜索路径:(7,2)→(5,4)→(4,7),取(4,7)为当前最近邻点。以目标查找点为圆心,目标查找点到当前最近点的距离2.69为半径确定一个红色的圆。然后回溯到(5,4),计算其与查找点之间的距离为2.06,则该结点比当前最近点距目标点更近,以(5,4)为当前最近点。用同样的方法再次确定一个绿色的圆,可见该圆和y = 4超平面相交,所以需要进入(5,4)结点的另一个子空间进行查找。(2,3)结点与目标点距离为1.8,比当前最近点要更近,所以最近邻点更新为(2,3),最近距离更新为1.8,同样可以确定一个蓝色的圆。接着根据规则回退到根结点(7,2),蓝色圆与x=7的超平面不相交,因此不用进入(7,2)的右子空间进行查找。至此,搜索路径回溯完,返回最近邻点(2,3),最近距离1.8。
这里写图片描述
参考来源:http://blog.csdn.net/u012422446/article/details/56486342

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值