KD树是一种对K维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。KD树其实就是二叉树,表现为对K维空间的一个划分,构造kd树至关于不断的用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域,即kd树就是二叉树在高维上的扩展。kd树的每一个节点最后对应于一个k维超矩形区域。kd树搜索的平均计算复杂度是\(O(logN)\)。假如维度是k, 而样本点一共N个,那么最好是\(N >> 2^k\)。不然kd树基于维度须要回溯比较的次数基本等同于线性一个个比较的次数。因此这时候一般会使用如sift中的近似最近邻方法(best-bin-first search),也就是不须要找到最匹配的那些样本点,而是放弃必定的精度来加快速度。html
在看别人博客的时候,发现对KD树有2种不一样理解,一种如统计学习方法中说的,树中内部节点也是样本点,如这里;而另外一种,树内部的节点是划分点,样本点全都在叶子节点上,如这里。数据结构
1.1 - 构造过程
这里先介绍内部节点是样本点的构造过程:
构造过程;假设训练集一共\(n\)个样本点,每一个样本点特征维度都是\(k\)。
1)构造根节点:先计算全部样本第1维组成的向量的中位数。而后将该中位数表示的样本做为根节点\(r_0\);将该维度上小于中位数的样本点划分到左子树\(RL\);大于该中位数的样本点划分到右子树\(RR\);
2)构造后续节点:对于步骤1)划分到左子树的全部样本点,按照它们第2维度找中位数,并将中位数对应的样本做为该子树的根节点\(r_{1l}\),将小于该中位数的样本点划分到该子树对应的左子树,大于的划分到该子树对应的右子树;
经过不断的找中位数表示的样本,不断的对k维空间进行分割,直到两边子树只剩下一个样本做为叶子节点。这样的kd树是平衡的,不过却不必定是最优的。app
ps:(1)当划分层数太深,而维度不够用时,从头开始,即从第1维接着开始; (2)树的每一个节点都对应一个样本。学习
拿《统计学习方法》例3.2来讲,假设训练集样本有{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}
第0层根节点,找第1维中位数对应样本点:[2,4,5,7,8,9],中位数从[5,7]中挑中7,得当前根节点为(7,2),分得左子树{(2,3),(4,7),(5,4)};右子树{(8,1),(9,6)}
第1层根节点,找第2维中位数对应样本点:左子树:[3,4,7]-4;右子树[1,6]-6。分得第1层
左子树{(2,3)}【(5,4)】{(4,7)};右子树{(8,1)}【(9,6)】
第2层,由于第一层分割后只剩下每一个根节点对应的左右子树都只有一个样本,做为叶子节点,因此无需再分,结果以下图:
spa
1.1.1 - 3维空间中的kd树
rest
1.2 - 搜索过程htm
这里以全部样本点为叶子节点作说明,叶子节点不参与中间的空间划分 (因懒于画图,直接找到了别人的图[3])
步骤:
blog
2.2 - 往上回溯
ip
完整的过程以下面几幅图:get
图2.5
图2.6
图2.7
参考资料:
[1] wiki,https://en.wikipedia.org/wiki/K-d_tree
[2] Beis, J.; Lowe, D. G. (1997). Shape indexing using approximate nearest-neighbour search in high-dimensional spaces. Conference on Computer Vision and Pattern Recognition. Puerto Rico. pp. 1000–1006
[3]Thinh Nguyen, Oregon State University. Lecture 13+: Nearest Neighbor Search (网页打不开可迅雷下载)