ball-tree
为了改进kd-tree沿着笛卡尔坐标进行划分的低效率,ball tree将使用超球面而不是超平面来划分空间。虽然在构建数据结构的花费上大过于kd-tree,但是在高维甚至很高维的数据上都表现的很高效。ball tree的节点保存圆心和半径,节点每次分裂都生成两个小的超球空间,不断分裂直至节点包含的数据点数量小于一定值,如下图所示。
(from:https://blog.youkuaiyun.com/skyline0623/article/details/8154911)
不同层次的圆被用不同的风格画出。树中的每个结点对应一个圆,结点的数字表示该区域包含的观测点数,但不一定就是图中该区域囊括的点数,因为有重叠的情况,并且一个观测点只能属于一个区域。
节点分裂方法如下:选择一个距离当前圆心最远的观测点i1,和距离i1最远的观测点 i2,将圆中其它观测点根据距离分别赋给这两个观测点所代表的簇,然后计算每一个簇的中心点和包含所有其所属观测点的最小半径。
使用ball tree时,先自上而下找到包含target的叶子结点,从此结点中找到离它最近的观测点。这个距离就是最近邻的距离的上界。检查它的兄弟结点中是否包含比这个上界更小的观测点。方法是:如果目标点距离兄弟结点的圆心的距离大于兄弟圆半径加上前面的上界的值(两圆不可能相交,三角形不等式),则这个兄弟结点不可能包含所要的观测点(如下图所示);否则,检查这个兄弟