如果我放宽一些约束,可以在近似最近邻居上获得算法快捷方式吗?

问题描述

我正在寻找一种算法,该算法每次查询的时间最快,类似于最近邻居搜索,但有两个区别:

  • 我只需要大致确定(容忍I型和II型错误)在某个距离 k 之内的邻居的存在,或者返回最近邻居的近似距离。
  • 我可以一次查询很多

我想要的吞吐量比那里的近似最近的邻居库(https://github.com/erikbern/ann-benchmarks)更好,后者似乎更适合单个查询。特别是,第一个条件的算法松弛似乎应该为算法捷径留出空间,但是我在文献中找不到任何解决方案,也无法弄清楚如何设计一个

这是我目前最好的解决方案,每个cpu每秒可处理约1万次查询。如果可能的话,我正在寻找接近数量级加速的东西。

sample_vectors = np.random.randint(low=0,high=2,size=(10000,vector_size))
new_vectors = np.random.randint(low=0,size=(100000,vector_size))

import annoy
ann = annoy.AnnoyIndex(vector_size,metric='hamming')
for i,v in enumerate(sample_vectors):
    ann.add_item(i,v)
ann.build(20)

for v in new_vectors:
    print(ann.get_nns_by_vector(v,n=1,include_distances=True))

解决方法

我对诸如您所链接的基准之类的基准有些怀疑,因为根据我的经验,我发现手头问题的定义在整个其他(可能外观相似)问题。

更简单地说,在给定基准测试中表现出色的算法并不能暗示在关注的问题上其表现更高。即使对问题的表述进行了微小的更改或看似微不足道的更改,也可以显着改变任何固定算法集的性能。

也就是说,鉴于您关心的问题的具体情况,我建议以下内容:

  • 使用论文[1]中描述的级联方法
  • 使用SIMD操作(intel芯片上的SSE或GPU)来加速,最近的邻居问题是更接近金属和并行性的操作可以真正发挥作用的
  • 调整算法参数以最大化您的目标;特别是[1]的算法具有一些易于调整的参数,这些参数将极大地影响性能以提高准确性,请确保对这些参数执行grid search以将其设置为 sweet发现您的问题

注意:我推荐论文[1],因为我尝试了您链接的基准测试中列出的许多算法,发现它们(对于图像重建任务)都比[ 1]同时比[1]复杂得多,这两个属性都是不受欢迎的。 YMMV取决于您的问题定义。

,

我很感谢这些解决方案,他们给了我一些想法,但是我会回答自己的问题,因为我找到了一个可以解决大部分问题的解决方案,也许将来会对其他人有所帮助。

我使用了基准测试中链接的一个库hnswlib,因为它不仅比烦人的性能略有提高,而且还具有批量查询选项。 Hnswlib的算法还允许高度灵活的性能/精度折衷以支持性能,这非常适合我要执行的高度容错的近似检查。此外,尽管并行化改进远非线性每核,但仍然有很多改进。在我的特定情况下,上述因素共同导致〜5倍加速。

正如ldog所说,您的里程可能会根据您的问题陈述而有所不同。