我有大约100M数字向量(Minhash指纹),每个向量包含0到65536之间的100个整数,我正在尝试使用{{3}对这个指纹数据库进行快速相似性搜索,即给定查询向量(例如[1,0,30,9,42,...]),找到该查询集与100M集数据库的交集/并集的比率。
要求是在笔记本电脑上以< 1秒(不包括索引/文件IO时间)返回查询向量的k个“最近邻居”。所以显然需要某种索引,问题是如何最有效的方法来解决这个问题。
注释: 我想过使用Jaccard similarity但是在这种情况下实际上需要知道集合的交集大小来识别SimHash而不是纯粹的相似性/相似性,但Simhash会丢失这些信息。
我尝试使用containment本书第3章中所述的简单locality sensitive hashing technique,将每个向量划分为20个“带”或长度为5的片段,将这些片段转换为字符串(例如[1] ,2,45,2,3] - >“124523”)并使用这些字符串作为散列表中的键,其中每个键包含“候选邻居”。但问题在于它为这些片段创建了太多候选者,而且频段数量的变化无济于事。
答案 0 :(得分:2)
解决此问题的一种方法如下:
(1)将向量排列到树(基数树)中。
(2)使用模糊标准查询树,换句话说,匹配是树的每个节点的值差异是否在阈值内
(3)从(2)生成包含所有匹配向量的子树
(4)现在,在具有较小阈值的子树上重复过程(2)
继续,直到子树有K个项目。如果K项目太少,则取上一个树并计算子树每个成员的Jacard距离,并排序以消除最差的匹配,直到您只剩下K个项目。
答案 1 :(得分:2)
我可能会有点迟到,但我会建议IVFADC indexing by Jegou et al.: Product Quantization for Nearest Neighbor Search
它适用于L2距离/点积相似性度量,并且有点复杂,但在时间和内存方面都非常有效。
它也在FAISS library for similarity search中实现,因此您也可以查看它。
答案 2 :(得分:1)
6年后回答我自己的问题,有一个使用多种算法来解决此问题的近似最近邻搜索基准:https://github.com/erikbern/ann-benchmarks,目前的获奖者是“ Hierarchical Navigable Small World graphs”:{{3} }
答案 3 :(得分:0)
您可以使用现成的相似性搜索服务,例如 AWS-ES 或 Pinecone.io。