Annoy 使用**多个随机投影树**和**基于优先队列的搜索**来有效地查找近似最近邻。其核心数据结构是二叉树森林,每棵树都通过使用随机超平面递归地分割数据集来构建。在树的构建过程中,Annoy 选择两个随机点,计算与它们等距的超平面,并根据数据点相对于该超平面的位置将数据划分为左/子节点。这个过程重复进行,直到节点达到预定义的大小。通过构建多棵树(例如,50 或 100 棵),Annoy 可以创建数据的多种不同分区,从而降低了任何单棵树中的不良分割影响查询结果的风险。然后,优先队列聚合和优化来自所有树中遍历的节点的候选邻居。
**随机投影树**通过缩小搜索空间来提高效率。例如,在像图像嵌入这样的高维数据集中,单棵树可能会沿着一个超平面分割空间,该超平面将“猫”和“狗”特征分开。另一棵树可能会根据颜色或纹理进行分割。在查询期间,Annoy 会遍历每棵树到最接近查询点的叶节点,并从这些节点收集候选邻居。这种随机性确保每棵树提供数据的不同“视图”,从而增加捕获真实邻居的可能性。**优先队列**在遍历过程中动态地维护前几个候选对象,避免与远距离点进行不必要的比较。这种并行树遍历和候选对象聚合的组合平衡了探索(检查不同区域)和利用(关注有希望的候选对象)。
这些策略从两个方面直接影响查询性能。首先,使用多棵树可以减少方差:即使一棵树的超平面与查询的对齐效果不佳,其他树也会进行补偿。例如,如果用户在数据集中搜索“红色汽车”,一些树可能会优先考虑基于颜色的分割,而另一些树则侧重于形状,从而确保找到相关的候选对象。其次,优先队列通过将精确距离计算限制为候选对象的一个小子集来最大程度地减少计算开销。Annoy 还允许调整树的数量和搜索深度,让用户可以在速度(较少的树,较浅的搜索)和准确性(更多的树,更深的搜索)之间进行权衡。这种灵活性使其适用于推荐系统等应用程序,在这些应用程序中,快速响应至关重要,但错过相关项目可能会降低用户体验。