有人可以告诉我Matlab使用的kNN搜索算法吗?

时间:2014-04-19 20:59:38

标签: matlab machine-learning knn

我为最近邻搜索编写了一个基本的O(n ^ 2)算法。像往常一样,Matlab 2013a的knnsearch(..)方法工作得更快。

有人能告诉我他们在实施过程中使用了哪种优化方式?

我可以阅读您可能指出的任何文件或文件。

PS:我理解网站上的文档提到了关于kd树的文章作为参考。但据我所知,当列数小于10时,kd树是默认选项。我的是21.如果我错了,请纠正我。

2 个答案:

答案 0 :(得分:7)

MathWorks在实现最近邻搜索时所做的最大优化是所有硬件都是在MEX文件中实现的,如编译C而不是MATLAB。

使用像kNN这样的算法(在我有限的理解中)是非常递归的并且难以矢量化,这可能会给出这样的改进,即O()分析只与相当高的n相关。

更详细地说,knnsearch命令使用createns来创建NeighborSearcher对象。默认情况下,当X少于10列时,这将是KDTreeSearcher个对象,当X超过10列时,它将是ExhaustiveSearcher个对象(两者都是KDTreeSearcherExhaustiveSearcherNeighborSearcher)的子类。

NeighbourSearcher的所有对象都有一个方法knnsearch(您很少直接调用,而是使用便捷命令knnsearch而不是此方法)。 knnsearch KDTreeSearcher方法直接调用MEX文件进行所有艰苦工作。它位于 matlabroot \ toolbox \ stats \ stats \ @KDTreeSearcher \ private \ knnsearchmex.mexw64。

据我所知,这个MEX文件几乎执行文档页面中引用的Friedman,Bentely和Finkel论文中描述的算法,没有任何结构变化。正如本文的标题所暗示的,该算法是O(log(n))而不是O(n ^ 2)。遗憾的是,MEX文件的内容无法进行检查以确认。

答案 1 :(得分:2)

code构建KD-tree空间分区结构以加快nearest neighbor search,将其想象为构建RDBMS中常用的indexes以加快查找操作。< / p>

除了最近邻搜索之外,此结构还会加速range-searches,从查询点查找距离r内的所有点。

正如@SamRoberts所指出的,代码的核心在C / C ++中实现为MEX函数。

请注意,knnsearch选择仅在特定条件下构建KD-tree,否则会回到穷举搜索(通过天真搜索所有点到最近的点)。

请记住,在非常高维数据(和少数实例)的情况下,算法会退化并且不会比穷举搜索更好。一般情况下,当您使用维度d>30时,搜索KD树的成本将增加到搜索几乎所有点,甚至可能比蛮力搜索更糟糕,因为构建树的开销很大。 / p>

该算法还有其他变体处理高维度,例如ball trees,它在一系列嵌套超球体中对数据进行分区(而不是像沿着笛卡尔轴一样对数据进行分区,如KD树) 。不幸的是,这些并未在官方统计工具箱中实现。如果您有兴趣,请参阅a paper,其中提供了对可用kNN算法的调查。

kdtree_search

(以上是搜索kd-tree分区的2d空间,借鉴文档)