【问题标题】:Implementing algorithm for closest vector search with O(log(n))用 O(log(n)) 实现最近向量搜索的算法
【发布时间】:2020-05-06 01:42:25
【问题描述】:
  1. 假设我有 n 个文档表示为单位向量,称之为 X。
  2. 我有一个文档的向量表示,称之为 Xi。
  3. 如何在没有暴力搜索(线性时间)的情况下找到 X 中与 Xi 最接近的*向量。

*距离可以是L2;当我们谈论单位向量时,比例等于余弦相似度。

我的近似方法(恒定时间): 1. 对每个向量维度的所有文档进行排序。 2.使用排序索引仅通过数据的子集进行暴力破解:f.e.包括每个向量维度的所有最接近的 1000 个文档,通过那些在所有(或大多数)维度中出现接近的文档(1000 个)计算 L2 距离。 (最多 1000 个)

但是我想知道是否有一个“更干净”的精确解决方案,例如最接近点对问题的分治算法,它在 log(n) 时间内运行。

PS:内存也应该线性扩展。但这应该没问题。

示例:我将 1M 文档的 100 维向量表示存储为 32 位浮点数。

  • 矢量表示:1M*100 dims*32bit = 3.2Gbit = 400MB
  • 排序索引:1M*100 sorts*32bit = 3.2Gbit = 400MB

【问题讨论】:

标签: algorithm math search nlp


【解决方案1】:

据我所知,没有一种算法可以在 O(log n) 最坏的情况下工作。然而,对于更多或更少随机分布的点,有一些精确的空间划分方法,平均为 O(log n)。如果您的文档集 X 是不可变的,则可以使用 k-d tree。如果您需要支持修改,您应该尝试R* tree,它更复杂但支持对X的插入和删除,并且它具有更一致的查询时间(但仍然平均为O(log n))。这两种结构都使用线性空间。

【讨论】:

    【解决方案2】:

    回答我自己的问题:

    到目前为止,我发现的最佳解决方案是来自 Spotify 的近似最近邻搜索(哦,是的):https://github.com/spotify/annoy

    除此之外,sklearn 还提供了一些快速近似最近邻搜索的功能。 https://scikit-learn.org/stable/modules/neighbors.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-25
      • 2013-05-05
      • 1970-01-01
      相关资源
      最近更新 更多