kd树简介 在matlab下VLFeat中的kd-tree使用
先简要介绍knn——K近邻算法和kd-tree——kd树,然后介绍matlab环境中有关使用kd树的函数。k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。
这里用的是在VLFeat 实现的kd树,其是一个开源的计算机视觉库,实现了 SIFT,MSER, k-means, hierarchical k-means, agglomerative information bottleneck, quick shift等算法。由C语言编写,提供MATLAB接口,文档详细。支持跨平台。
1、KNN
先从KNN讲起吧,何谓KNN算法,全称为:K-Nearest Neighbor algorithm,即K近邻算法。
用官方的话来说,所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居),这K个实例的多数属于某个类,就把该输入实例分类到这个类中。
K近邻算法的核心在于找到实例点的邻居,这个时候,问题就接踵而至了,如何找到邻居,邻居的判定标准是什么,用什么来度量。特征空间中两个实例点的距离可以反应出两个实例点之间的相似性程度。K近邻模型的特征空间一般是n维实数向量空间,使用的距离可以使欧式距离,也是可以是其它距离。
2、Kd-Tree
那什么又是Kd-树呢, Kd-树其实是K-dimension tree的缩写,是对数据点在k维空间中划分的一种数据结构。其实,Kd-树是一种平衡二叉树。k-d树是一种空间划分树,说白了,就是把整个空间划分为特定的几个部分,然后在特定空间的部分内进行相关搜索操作。
kd树按照一定的划分规则把这个三维空间划分了多个空间
3、matlab中kdtree的使用
3.1 建立 —— vl_kdtreebuild
先举个栗子,在matlab环境中,
X表示100个2维列向量。
vl_kdtreebuild在X数据集上建立kd树。参见kd树建立的算法:
3.2 查询 —— vl_kdtreequery
给出一个查询点Q,vl_kdtreequery 函数返回在X中与Q最近的数据点:
index为与Q最近的点在X中的下标,distance为X(index)和Q之间的欧式距离的平方。
kd树是一个层次结构,其是按最大方差的维度,将数据集递归划分建立起来的。在每一次迭代中,计算每维的方差,然后数据按有着最大方差的那个维度被划分为两部分。分割阈值可以设为均值或中位数(使用vl_kdtreebuild函数的ThresholdMethod选项)。
kd树对同一数据集的划分,使用均值作为阈值(前图)和中位数作阈值(后图)。图中右下角为一个查询点通过vl_kdtreequery查询最近10个近邻。图通过 vl_demo_kdtree函数得来。
vl_kdtreequery使用最优节点优先算法(best-bin-first,BBF)进行探查。这是一种分支限定法,其维护一个从查询点到任意数据点的所有开路径的最小距离估计。
vl_kdtreequery支持两种重要的操作,近似最近邻匹配(approximate nearest-neighbor ,ANN)和K近邻查找。
KNN用于返回查询点Q的k个近邻,例如:
返回Q在X中最近的10个邻居和它们的距离,存在index和distance中。
MaxComparisons 选项用于执行ANN查询。这个参数指明在kd树的BBF查找中探查多少条路径,并在结束之前返回目前找到的最好结果:
Q在X中最多与15个点比较。
查找10个最近邻,关于不同MaxComparisons 的值的结果。可以看出,MaxComparisons 指明了最多比较的次数,即使NumNeighbors大于MaxComparisons 时,函数也会在达到最多比较次数后返回。图来自vl_demo_kdtree_ann函数。
参考:
1.vlfeat.org官网上关于kdtree的介绍:http://www.vlfeat.org/overview/kdtree.html
2. 博客:从K近邻算法、距离度量谈到KD树、SIFT+BBF算法http://blog.csdn.net/v_july_v/article/details/8203674
3. 博客:KD树核心思想简介 http://www.cnblogs.com/snake-hand/archive/2012/08/13/2636236.html