`

k-d tree

 
阅读更多

k-d tree

 

k-d(k-dimensional tree)是一种空间数据分割结构,对于组织在d维空间的数据进行搜索,典型的应用如范围搜索(Range Search)和最邻近搜索(Nearest Search)。这两个术语有没有感觉很熟悉,在机器学习Clustering算法中经常用到这两个功能,如DBSCANOPTICS等算法。

在使用Range QueryNearest Search过程中,如果使用遍历的方法也能完成数据空间的搜索功能,缺点很明显:穷举遍历会造成性能下降。穷举法对于数据集合本身的结构信息没有使用,大大浪费了数据的特性;如果能预先根据数据特点建立索引,能在查询过程中快速匹配,就能够加快数据检索的速度。k-d树的算法目的是对高维空间索引数据进行结果和近似查询,如快速的找到查询数据点的近邻;查找符合查询条件的范围(Range)等。

k-d树的查询有两种基本方式:

K-Neighbor Search:给定数据点及正整数K,从数据集合中查找到距离查询点最近的K个数据,kNN(K-Nearest Neighbor)算法对这种查询索引树数据结构是极其重要的。

Range Query:给定查询点和查询距离阀值,从数据集合中找到所有距离查询点小于阀值的数据点。

 

k-d树是一种特殊的二叉树,其中每个数据节点都是k(k-dimensional)数据。其中每个非叶子节点都是对数据点在一个维度上一个划分:二维空间的划分是线,超过二维划分是一个超平面。如果你还是不熟悉的话,可以将K维数据缩减为1维数据,这样的话k-d树就收缩为1维平衡二叉树。再将1维数据扩张为k维,将每个非叶子节点看做是在多维数据中其中一维数据的划分,在这个维度上的数据点按照左小右大划分到子节点上。

k-d树的主要操作有:构建和查询。构建是预处理操作,将数据点构建成k-d树,方便后来的数据进行查询;查询时即时操作,在生成的k-d树中查找符合条件的数据点。下面的示例来自wiki,是二维数据点上的教程:

[(2,3), (5,4), (9,6), (4,7), (8,1), (7,2)]

生成的k-d树如下图所示:

上图中的左侧的X和Y是划分的坐标,表示对右侧的数据点x纬度或者Y纬度进行划分,我们用一种更为简单的方式来表明这个过程:

该图中的红线和蓝线就是我们的划分标准:其中红线是对于X轴划分,红线对应于Y轴划分。那么划分过程是怎样的呢?我们详细看下k-d树的构建过程,当然你也可直接参考wiki上的构建过程:


 

k-d树构建过程中,depth为偶数按照x轴划分,depth为奇数的话从y轴划分,wiki上的划分是按照纬度依次划分,我们这里的举例是二维空间数据。划分是指选择从数据空间中选择一个维度,再对该纬度上的数据进行操作。这个操作比较简单,就是在该维度上对数据排序,选择中间点为锚点(Axis),将数据划分为锚点左(P1)(P2),然后再重复迭代树的构建过程。

 

构建k-d树过程中有三个过程需要注意:

数据纬度选择:在上面中根据深度选择数据的纬度,这个其实并不好,通常的做法是将数据点按照纬度进行方差计算,选择方差最大的那个纬度进行纬度划分。方差越大,说明纬度分散性越好,越有利于数据划分。

数据纬度排序:将数据点在选定的纬度上进行排序,注意这个排序是数据点中的一个维度,在Python中很好实现。

数据划分:排序后将数据集合进行划分,分为LeftRight,在后面迭代计算(我为什么要写这个呢?如果优先考虑内存使用的话,这个该怎么做)

 

k-d树的构建不难,我面我们看下k-d树的查找。k-d树的查找才是匹配的重要步骤,下面我们看下k-d树的最邻近查找算法。


 

算法中的region操作计算出数据点与周边数据点的关系,lc操作定位出数据点位置。

 

wiki上有非常详细的Nearest Neighbor Search描述,建议大家仔细看下。如果感觉英文有问题的话,可以参考下https://github.com/ubilabs/kd-tree-javascript这里面的代码,交互学习。在这个链接里,有四个工程都使用了k-d树结构,推荐使用color那个项目,核心功能比较简单,能够快速入手。其实如果不在乎展示样式的话,可以直接看kdTree.js:http://ubilabs.github.com/kd-tree-javascript/kdTree.js,这里面的纬度选择也是根据深度(Depth)确定,大家可以选择自己的纬度选择实现。

 

复杂度分析:

查询过程中,如果查询点的邻域与分割面(Axis确定)相交时,就需要查询分割面的另一面,导致检索过程比较复杂,效率下降。研究表明Nk维数据点形成的k-d树的搜索过程最差为:

 

k-d树是一种特殊的高维树结构,那么针对树节点的添加(Add)、删除(Delete)、树平衡(Rebalance)都是一个需要考虑的操作。根据上面的流程,添加或者删除树节点都会使得树平衡性受影响,如果每次都对树进行rebalance会使得代价过高。参考文献二中提出的延迟Rebalance倒是个不错的解决方法,就是将数据的添加直接附加到响应位置,删除只是标记删除字段,到树过于不平衡时再进行Balance操作。不过在平衡操作之前,树的这种非平衡结构对于Range QueryNearest Search造成的影响需要评估下。

 

 k-d树的平均时间复杂度如下图,这个不用仔细分析,在Average情况下要好于线性查找,最差情况下和线性查找相当;该图截取自wiki上:

 

在本文的最后,我们关于k-d树必须知道的内容:

在高维空间(High Dimensional Space,注意用词)中,k-d树并不能有效(Efficiently)的查找Nearest Neighbor数据。一般来说当N>>2**k时,k-d树的查找才会有优势,和穷举搜索(Exhaustive Search)相比;否则的话就应该使用近似最近搜索方法(Approximate Nearest Neighbour Methods)。关于近似最近搜索的进一步深入了解,请参考:Handbook of Discrete and Computational Geometry(2nd)的第29章:Nearest neighbours in high-dimensional spaces,这部分的内容我也没有深入学习过,需要找时间学习下。 

 

关于k-d树的内容就到这里,熟悉k-d树对于机器学习来说是个很重要的内容,尽管现在的很多Machine Learning示例代码都不会涉及这个内容;实际在工程中,这些考虑都是很现实的内容。

 

 

参考文献:

http://www.cise.ufl.edu/class/cot5520fa09/CG_RangeKDtrees.pdf,该class包含许多跟计算几何相关的内容,推荐保存。

http://www.autonlab.org/autonweb/14665/version/2/part/5/data/moore-tutorial.pdf

 

 

 

 

 

  • 大小: 20.7 KB
  • 大小: 4.9 KB
  • 大小: 73.6 KB
  • 大小: 107.7 KB
  • 大小: 1.6 KB
  • 大小: 3.5 KB
分享到:
评论

相关推荐

    基于k-d tree的邻域搜索

    经过整理的k-d tree搜索k近邻的算法,直接输入参数就可以用了,一个主函数,调用两个子函数

    K-D Tree_翁家翌.pdf

    K-D Tree_翁家翌.pdf

    k-d tree资料

    The kd-tree is a binary tree in which every node is a k-dimensional point.K-D树,K表示空间的维数。 它的每一层通过检测不同的属性(关键字)值以决定选择分枝的方向。在二维空间中(也就是2-D树)在根和偶数层...

    k-d tree在传统OI数据结构题中的应用_任之洲.pdf

    k-d tree在传统OI数据结构题中的应用_任之洲.pdf

    K-D tree原理查找.pdf

    主要介绍K-D树的创建过程;创建原理;针对空间区域的碰撞结构做了应用导向

    knn.zip_K._k-d tree_kd tree knn_k近邻搜索

    这是一个小而有效的程序来执行的K -近邻搜索算法,此算法利用JIT 理论加速循环,比向量化有效...甚至比kd-tree效果要佳。 K-nearest neighbor search已经广泛应用在科学与工程上,比如模式识别,数据挖掘和信号处理。

    k-dtree matlab

    一个建立k-d树,并且搜索k-d树节点进行最近点匹配的代码,采用matlab完成

    并行表面积启发式K-D树结构ParKD.zip

    ParKD (Parallel k-D Tree Construction,并行 K-D 树)。k-D树是用于射线的充分研究的加速度数据结构跟踪。它用于组织场景中的图元以允许高效执行光线和图元之间的交叉操作。使用贪心算法可以获得最高质量的k-D树...

    kdtree 算法图

    一个算法来的 ...【实验内容】:K-D tree数据结构算法 【实验准备】:VC++编程环境软件;测试数据 【实验步骤】: 1. 先阅读教材上关于k-d tree的说明与描述 2. 设计算法实现基本数据结构 点的数据结构

    开源项目-Kyroy-kdtree.zip

    开源项目-Kyroy-kdtree.zip,Kyroy/kdtree: A k-d tree implementation with Insert & Remove

    matlab开发-kDtree

    matlab开发-kDtree。使用K-D树实现执行最近点搜索或范围查询。

    数据结构Advanced-Data-Structures

    Adaptive k-d tree 420 Quadtree 421 Octree 427 Linear octrees 429 Z-order 429 UB-tree 434 R-tree 435 R+ tree 441 R* tree 442 Hilbert R-tree 445 X-tree 452 Metric tree 452 vP-tree 453 BK-tree 454 Hashes...

    论文研究-基于多判别参数混合方法的散乱点云特征提取.pdf

    对点云构建k-d tree,利用k-d tree建立点云K邻域;针对每个K邻域计算数据点曲率、点法向与邻域点法向夹角的平均值、点到邻域重心的距离、点到邻域点的平均距离,据此四个参数定义特征阈值和特征判别参数,特征判别...

    kdtree实现源码(C++) 范围查询

    kd-tree(k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。K-D树是二进制空间分割树的特殊的情况。 在计算机科学里,k-d树( k-维树的...

    C语言的KD树实现 kdtree

    Kd-trees 是二叉树扩展到K维的一种数据结构,可进行方便快速的查找和邻点查询。

    A Fast ICP Algorithm for 3-D.pdf

    Abstract—Iterative closest point (ICP) algorithm has been widely used for registering the geometry, shape and ... Theproposedfast ICPisabout 3.17 times faster than the existing ICP such as the K-D tree.

    KNN.zip_K._k nearest neighbor_knn kd tree_邻域

    c++实现的KNN库:建立高维度的K-d tree,实现K邻域搜索,最小半径搜索

    ICP-point-cloud-registration.zip_ICP Registration_ICP 激光点云_三维配准_

    的点云初始位置,然后在经典 ICP 算法的基础上,采用 k - d tree 结构实现加速搜索,并利用方向向量夹角阈值去除 错误点对,提高算法的效率。实验表明,本算法流程在保证配准精度的前提下,显著提高了配准效率。

    论文研究-基于多判据的散乱点云特征点提取算法.pdf

    首先利用一种改进的k-d tree构建点云拓扑,搜索样点的K局部邻域;然后利用法向夹角判定准则、核密度判定准则、场力和判定准则分别求取各个样点局部邻域的三个特征参数,最后通过加权计算特征参数得到每个样点的特征...

    基于pcl库的KD-tree算法

    kdtree的源码,用于压缩点云数据,能够让ICP算法更加快速.k-d树 [1] (k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。K-D树是二进制...

Global site tag (gtag.js) - Google Analytics