kd树

目录

  • 引入kd树
  • 构造kd树
  • kd树搜索

引入kd树

     k k k近邻实现的方法是线性扫描。需要计算输入与每个训练实例的距离。如果训练集非常大,那么计算非常耗时。为了提高 k k k近邻搜索的效率,可以使用特殊的结构来存储训练数据,以减少计算距离的次数, k d kd kd树就是其中的一种方法。
     k d kd kd树是一种对 k k k维空间种的实例点进行存储以便对其进行快速检索的树形数据结构。
     k d kd kd树是二叉,是对 k k k维空间的一个划分。
    kd树和KNN选择的方法:
        假设一个数据有N个样本,维度维k。
            1.当 N > > 2 k N >>2^{k} N>>2k,选择 k d kd kd
            2.当k维空间接近训练实例数(N)时,选择KNN,因为 k d kd kd的效率会迅速下降,几乎接近线性扫描

构造kd树

    kd树的构造方法:

  1. 构造根节点,使根节点对应于k维空间中包含所有实例点的超矩形区域。
  2. 通过递归的方法,不断的对 k k k维空间进行切分,生成子节点。
  3. 切割的方法:在超矩形区域上选择一个坐标轴和这个坐标轴上的中点,通过过中点垂直于坐标轴将当前的超矩形区域切分维两个子区域。一直重复这个过程,直至没有可切分的点。

    中值选择

  1. 对原始数据点在所有维度进行一次排序,存储下来,在以后的过程中只需查找不需计算。
  2. 从原始数据中随机选择固定数目的点,然后对这些点进行排序,每次从这些样本点中选择中值,来切分超平面,该方法具有很好的性能和平衡性。

    例子
        二维平面点(x,y)的集合X={ ( 2 , 3 ) , ( 5 , 4 ) , ( 9 , 6 ) , ( 4 , 7 ) , ( 8 , 1 ) , ( 7 , 2 ) (2,3),(5,4),(9,6),(4,7),(8,1),(7,2) (2,3)(5,4)(9,6)(4,7)(8,1)(7,2)}。以此为例,构建一个 k d − t r e e kd-tree kdtree

  1. 构建根节点时,此时的切分维度为x,以上集合点在x维从小到大排序为(2,3),(4,7),(5,4),(7,2),(8,1),(9,6);其中值为(7,2)。
    注: 2,4,5,7,8,9在数学中的中值为(5 + 7)/2=6,但因该算法的中值需在点集合之内, 所以中值计算用的是len(X)//2=3, sorted[3]=(7,2)。

  2. 所以(2,3),(4,7),(5,4)挂在(7,2)节点的左子树,(8,1),(9,6)挂在(7,2)节点的右子树。

  3. 构建(7,2)节点的左子树时,集合点为{(2,3),(4,7),(5,4)},此时的切分维度为y,中值为(5,4)作为分割平面,(2,3)挂在其左子树,(4,7)挂在其右子树。

  4. 构建(7,2)节点的右子树时,集合点{(8,1),(9,6)},此时的切分维度也为y,中值为(9,6)作为分割平面,(8,1)挂在其左子树。至此 k d kd kd-tree构建完成,如下图所示。

kd树_第1张图片

kd树搜索

    k 近 邻 k近邻 k

  1. 找到包含目标点的叶节点,以目标点和叶节点的距离为半径画圆。
  2. 退回父节点,如果父节点的另一个节点的超矩形区域与圆相交,在这个区域内找出这些点。
  3. 退回到更上一级的父节点,继续以上操作。
  4. 如果父节点的零一节点的超矩形区域与超球体不相交,则该区域不存在更近点

    例子
设点x=(5.2,5.4)

  1. 找到包含x的叶节点。x点的x维值为5.2,小于中点值7,所以落到(7,2)的左子节点,x的y维值为5.4,大于y维的中点4,所以落在了(5,4)的右子节点。因此包含x的叶节点为(4,7)。最近邻点一定在以x为圆心,以x点到(4,7)距离为半径的圆内。
  2. 返回父节点(5,4),看是否在圆内,如果在则为最近点
  3. 查看(5,4)的左节点看是否相交,不相交则没有最近点,否则计算距离。
  4. 继续退回父节点(7,2)看是否相交
  5. 查看(7,2)的右节点是否在圆内
  6. 查看(8,1)是否与圆相交
  7. 在以上里面寻找最近点

你可能感兴趣的:(kd树)