k近邻法的实现:kd树

实现k近邻法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索,尤其时在训练样本容量大或者特征空间维数高的情况下。k近邻最简单的实现方法是计算出输入实例与所有样本的距离,然后选择其中最近的k个。显然这种方法是非常耗时的。为了提高k近邻搜索的效率,可以使用特殊的结构存储训练数据,以减少计算距离的次数,kd树就是其中的一种方法。

1. 构造kd树

kd树是一种树形结构,是二叉树,表示对k维空间的一个划分,构造kd树相当于不断的用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个节点对应于一个k维超矩形区域。
输入:k维空间数据集T = {X 1 ,X 2 ,...,X N },其中,
输出:kd树
(1)开始:构造根节点,根节点对应于包含T的k维空间的超矩形区域。
选择为坐标轴,以T中所有实例的坐标的中位点为切分点,将根节点对应的区域切分为两个子区域,切分由通过切分点并与坐标轴垂直的超平面实现。由根节点生成深度为1的左右子结点(此时的结点是一个区域,里面可以包含许多实例,左节点对应于坐标小于的区域,右节点对应与坐标大于的区域)。
(2)重复:对深度为j的结点(此时的结点是一个区域),选择为切分的坐标轴,m=(j mod k)+1,以该结点的区域中所有实例的坐标的中位点为切分点,将该结点对应的矩形区域切分为两个字区域,切分由通过切分点并与坐标轴垂直的超平面实现。
(3)直到切分后的两个字区域内没有实例存在时停止,从而形成了kd树的区域划分。
实例:
k近邻法的实现:kd树_第1张图片
该例共含有三个实例(T1,T2,T3),首先以x轴坐标划分,T1的x坐标为切分点,T1为根节点,它代表的区域为整个空间,两个子结点为(T2,T3),T2代表的区域为B+C,T3代表的区域为A+D。然后以y轴坐标划分,此时是在两个结点区域中都进行的。最终形成了上述特征空间的划分。

2. 搜索kd树

输入:已构造的kd树:目标点x;(辅助结构,最大堆)
输出:x的k近邻
公共操作P:在访问每个结点时,若最大堆容量不足k,则将该结点加入最大堆,若堆容量以达到k,则比较当前节点是否比堆顶元素与x的距离更近,若更近则以当前节点代替堆顶结点,并调整堆。
(1)从根节点出发,递归地向下访问kd树,若目标x当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点,知道结点为叶节点为止。执行公共操作P。
(2)递归的向上回退,在每个节点进行以下操作:
(a)执行公共操作P。
(b)检查该子结点的兄弟结点区域是否有比堆顶元素更近的点或堆容量未满。具体的,检查另一子结点对应的区域是否与以目标点为求心,以目标点与堆顶元素距离为半径的球体相交。
如果相交或容量未满,以另一子结点为根节点执行(1)。
(4)当回退到根节点时,搜索结束,堆中实例即为所求实例。

参考文献:统计学习方法

你可能感兴趣的:(机器学习(Machine,Learning))