k近邻算法的kd树实现原理

本文参考 《统计学习方法》 李航

k近邻

k近邻又叫KNN,是一种基本分类方法。k近邻假设给定一个训练数据集,其中实例类别已定,分类时,对于新的实例,根据其k个最近邻的训练实例类别,通过多数表决的方式进行预测。

k近邻的kd树实现

k近邻有一个很大的缺陷就是搜索速度比较慢,最简单的搜索方式就是对训练样本线性遍历,当训练数容量很大时,算法耗时难以接受。

kd树:
kd树是一种对k维空间实例点进行存储以便于快速检索的数据结构,kd树是二叉树,表示对k维空间的划分,构成一些列k维超矩形区域,每一个节点对应一个k维超矩形区域。
kd树的构造方法:
kd树的构造有点类似于线段树,大致相当于对线段树的一个维度拓展。
根节点包含所有k维空间的实例,通过递归方式,不断对k维空间切分,生成子结点。在超矩形区域选择一个坐标轴,用垂直于坐标轴的超平面将空间分成两份,一直到子区域没有实例终止。
即以下步骤:
1)构造根节点,对应于k维空间的超矩形区域。
选择 x(1) 为坐标轴,以所有实例的 x(1) 坐标的中位数为切分点,将超矩形区域分成两个子区域。生成两个深度为1的左右子树。将 x(1) 维度的值小于切分点的实例放到左子树,大于切分点的放到右子树,等于切分点的存在当前节点中。
2)重复上述步骤,对于深度为j的结点,选择 x(l) 为切分的坐标轴,其中 l=j(modk)+1 ,按照上述规则切分新的维度。
3)直到左右区域没有新的实例点终止。
kd树的搜索:
以最近邻为例:
给定一个目标点,搜索其最近邻,首先找到包含目标点的叶结点。然后从该叶结点出发,依次退回父节点,不断查找与目标点最近邻的节点。
1)在kd树中找到包含目标点 x 的叶结点。(从根递归向下查找)
2)以此叶结点为“当前最近点”
3)递归向上退回,对每个节点进行一下操作:
a)如果该节点离 x 更近,则更新“当前最近点”
b)当前最近点一定存在于该节点的一个子节点对应的区域,检查该子节点兄弟节点区域是否有更近的点。具体的,检查兄弟结点对应区域是否与以 x 为球心,目标点与“当前最近点”间的距离为半径的超球体相交。如果相交,在子结点进一步搜索,如果不相交,直接剪枝。
4)退回到根节点时搜索结束
kd树的平均搜索时间复杂度为 log(N) ,其中N为训练样本数。

你可能感兴趣的:(算法,统计学)