允许快速余弦距离的理想数据库是什么?

数据挖掘 特征提取 数据库
2021-10-06 06:35:10

我目前正在尝试将许多特征向量存储在数据库中,以便根据要求将传入的特征向量与存储在数据库中的许多其他(如果不是全部)进行比较。我需要计算余弦距离,并且只返回例如前 10 个最接近的匹配项。这样的向量的大小约为 1000 左右。

每个请求都会有一个特征向量,并且需要与属于 db 中的一个子集的所有特征向量进行比较(在最坏的情况下,这很可能是每个子集的数千个条目)。

哪个数据库提供了有效运行此类查询的灵活性?

我研究了 postgres,但我想知道是否有更适合这个问题的替代方案。不确定这很重要,但我很可能会使用 Python。

我发现这篇文章是关于在 SQL 中做的。

编辑:我对不一定与 SQL 相关的这个问题的替代解决方案持开放态度。

4个回答

如果您将来需要扩展超过 1000 个条目,那么从计算的角度来看,寻找确切邻居的蛮力方法将变得越来越令人望而却步。为了让您的解决方案面向未来,我建议您研究经过充分研究的近似最近邻 (ANN) 技术领域。显然存在速度/准确性权衡,但在撰写本文时,确实没有其他方法可以将您的搜索扩展到数百万或数十亿个条目。

大型科技公司几乎完全依赖这些技术。想一想...

  • Facebook 查询相似的面孔以建议人们在您的照片中添加标签
  • Spotify 推荐语义相似的歌曲
  • Google 搜索与您上传的图片相似的图片

这篇文章很好地概述了当前最先进的算法及其优缺点。下面,我链接了几个流行的开源实现。所有 3 个都有 Python 绑定

如果只有几千个条目,每个条目都有 1,000 个功能,那么如果您在某种服务器上运行它,您可能只能将其保存在 RAM 中。然后当你得到一个新的特征向量时,只需运行余弦相似度例程。一个简单的方法就是使用像 pandas 和 scikit-learn 这样的标准。

或者,您可以将所有内容保存在 SQL 中,将其加载到 pandas 之类的内容中并使用 scikit-learn。

实际上,我不确定通过用 SQL 本身编写计算是否会大大加快速度(如果有的话)。

如果您担心数据集太大以至于常规数据库可能无法处理它,您可以考虑替代实现,例如SimHash

来自维基百科,

在计算机科学中,SimHash 是一种快速估计两组相似程度的技术。Google Crawler 使用该算法来查找附近的重复页面。它是由摩西 Charikar 创建的。

这是来自谷歌的研究论文,这里有几个Python实现

蛮力方法具有 O(n) 的搜索复杂性,无论您是在 Python 还是数据库中进行。对于更快的查询,您需要一个树结构的多维查找表,例如kd 树对于 Python,在SciPyScikit-Learn中都有 kd 树的实现

如果您需要独立的数据库解决方案,请参阅: