我正在查看KD树的维基百科页面。作为一个例子,我在python中实现了用于构建列出的kd树的算法。
然而,使用KD树进行KNN搜索的算法切换语言并不完全清楚。英语解释开始有意义,但它的一部分(例如它们“展开递归”以检查其他叶子节点的区域)对我来说并没有任何意义。
这是如何工作的,如何在python中使用KD树进行KNN搜索?这不是一个"send me the code!"
类型的问题,我不希望如此。请简单解释一下:)
答案 0 :(得分:14)
这book introduction,第3页:
给定d维空间中的一组n个点,构造kd树 递归如下。首先,找到第i个值的中值 点的坐标(最初,i = 1)。也就是说,计算值M, 这样至少50%的点的第i个坐标大于或等于 到M,而至少50%的点的第i个坐标更小 大于或等于M.存储x的值,并对集合P进行分区 进入PL和PR,其中PL仅包含具有第i个坐标的点 小于或等于M,| PR | = | PL |±1。然后重复该过程 递归地在PL和PR上,i替换为i + 1(或1,如果i = d)。 当节点上的点集具有大小为1时,递归停止。
以下段落讨论了它在解决最近邻居时的用法。
或者,这是original 1975 paper by Jon Bentley。
编辑:我应该补充一点,SciPy有一个kdtree实现:
答案 1 :(得分:9)
我自己花了一些时间来解释算法的Wikipedia描述,并提出了以下可能有用的Python实现:https://gist.github.com/863301
closest_point
的第一阶段是一个简单的深度优先搜索,以找到最匹配的叶节点。
不是简单地返回找到备份调用堆栈的最佳节点,而是在第二阶段检查“离开”端是否有更近的节点:( ASCII art diagram)
n current node
b | best match so far
| p | point we're looking for
|< >| | error
|< >| distance to "away" side
|< | >| error "sphere" extends to "away" side
| x possible better match on the "away" side
当前节点n
沿着一条线分割空间,因此如果点p
和最佳匹配{{1}之间的“错误”,我们只需要查看“离开”侧}}大于距离点b
和p
之间的距离。如果是,那么我们检查“离开”一侧是否有更近的点。
因为我们的最佳匹配节点被传递到第二个测试中,所以它不必对分支进行完全遍历,并且如果它位于错误的轨道上将会很快停止(仅向下朝向“近”子节点,直到它击中一片叶子。)
要计算点n
与通过节点p
分割空间的线之间的距离,我们可以通过将适当的坐标复制为轴来简单地将点“投影”到轴上都是正交的(水平或垂直)。
答案 2 :(得分:0)