K近邻算法(kNN)学习——kd树


    之前做机器学习相关实验的时候就使用过K近邻(kNN)算法,但是那时只是停留在简单的了解阶段,并没有对该算法深层次的原理进行研究,最近我通过学习《统计学习方法》一书,对kNN算法有了深入的理解,下面我将结合自己的学习总结一下kNN相关的内容:

一、kNN算法的简介


    kNN算法是一种基本的分类与回归方法,其基本原理是:给定一个训练数据集,对新输入实例,在训练数据集中找到与该实例最近邻的K个实例,这k个实例的多数属于某个类别,就把该输入实例分为这个类别。
    k-NN算法的三要素是:距离度量k值的选择分类规则。常用的距离度量是欧式距离以及更一般的 Lp 距离。k值小时,k近邻模型更复杂;k值大时,k近邻模型更简单。k值的选择反映了对近似误差与评估误差之间的权衡,通常由交叉验证方法来选择最优的k。常用的分类决策规则是多数表决,对应于经验风险最小化。
    在k-NN算法中,当训练集、距离度量、k值以及分类规则确定后,其结果是唯一确定的。

二、kNN算法的实现:kd树


    kd树是一中便于对k维空间中的数据进行快速搜索的数据结构(注意,k不是k个邻居的意思)。kd树是一种二叉树,表示对k维空间的一个划分,其每个节点对应于k维空间划分中的一个超矩形区域。利用kd树可以省去对绝大部分数据的搜索,从而减少搜索的计算量。

1.kd树的构造


    构造kd树的过程我自己总结了一个口诀就是:“选择中位数,一横一竖”
    构造平衡kd树算法
    输入:k维空间数据集 T={x1,x2,...,xN} ,其中 xi=(x(1)i,x(2)i,...,x(k)i) i=1,2...,N;
    输出kd树。
    (1)分别基于输入的数据集,计算k维数据中方差最大的一维(也可以依次分割每一维度),为了便于介绍,本算法以依次分割每一维度进行的,所以选择 x(1) 为分割坐标轴;
    (2)选择 x(1) 为分割坐标轴,以T中所有实例的 x(1) 坐标的中位数为切割点,将根节点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴 x(1) 垂直的超平面实现。
    由根节点生成深度为1的左、右子节点:左子节点对应坐标 x(1) 小于切分点的子区域,右子节点对应于坐标 x(1) 大于切分点的子区域。
    (3)重复步骤(2),对于深度为j的节点,选择 x(l) 为切分点的坐标轴, l=j(modk)+1 ,以该节点的区域切中所有实例的 x(l) 中位数为切分点,将该节点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴 x(l) 垂直的超矩形实现。
    (4)停止条件:直到两个子区域内没有实例存在时停止。
    举例:
    假设有6个二维数据点 {2,3,5,49,64,78,17,2} ,数据点位于二维空间内,如图1:
    a)依次分割每一维度,因此先分割x轴;
    b)根据x轴方向的值2,5,9,4,8,7排序选出中值为7,所以以(7,2)为分割点。这样,该节点的分割超平面就是通过(7,2)并垂直于x轴的直线x = 7;
    c)确定左子空间(x <= 7的部分)和右子空间(x > 7的部分)进行上面两步递归操作直到空间中只包含一个数据点。最后生成的kd树对应的空间划分为图1,kd树如图2。


特征空间划分
图1 kd树对应的空间划分


kd树
图2 kd树示例

2.kd树的最近邻搜索


    给定一个目标点,搜索其最近邻,首先找到包含目标点的叶节点,然后从该叶节点出发,依次退回到其父节点,不断查找是否存在比当前最近点更近的点,直到退回到根节点时终止,获得目标点的最近邻点。如果按照流程可描述如下:
    1. 从根节点出发,若目标点x当前维的坐标小于切分点的坐标,则移动到左子节点,反之则移动到右子节点,直到移动到最后一层叶节点。
    2. 以此叶结点为“当前最近点”
    3. 递归的向上回退,在每个节点进行如下的操作:
    a.如果该节点保存的实例点距离比当前最近点更小,则该点作为新的“当前最近点”
    b.检查“当前最近点”的父节点的另一子节点对应的区域是否存在更近的点,如果存在,则移动到该点,接着,递归地进行最近邻搜索。如果不存在,则继续向上回退
    4. 当回到根节点时,搜索结束,获得最近邻点
    以上kd树的最近邻搜索分析,即k=1时的情况。当k>1时,在搜索时“当前最近点”中保存的点个数<=k的即可。
    相比于线性扫描,kd树搜索的平均计算复杂度为O(logN).但是当样本空间维数接近样本数时,它的效率会迅速降低,并接近线性扫描的速度。因此kd树搜索适合用在训练实例数远大于样本空间维数的情况

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值