← 返回博客
跳至主要内容

向量搜索中的距离度量

·阅读需 12 分钟
Erika Shorten

Distance Metrics in Vector Search

向量数据库 - 比如 Weaviate - 使用 机器学习模型 来分析数据并 计算向量嵌入。这些向量嵌入与 数据一起存储 在数据库中,之后用于查询数据。

简而言之,向量嵌入是用于描述对象的数字数组。例如,草莓可以有一个向量 [3, 0, 1] – 实际上,数组通常会比这长得多。

注意,数组中每个值的含义取决于我们用于生成它们的机器学习模型。

为了判断两个对象有多相似,我们可以使用各种 距离度量 来比较它们的向量值。

在 向量搜索的语境下, 相似度度量 是一个函数,它接受两个向量作为输入,并计算它们之间的距离值。距离可以有多种形式,可以是两点之间的几何距离,也可以是向量之间的角度,还可以是向量分量差异的计数等等。最终,我们使用计算出的距离来判断两个向量嵌入有多接近或多远。这些度量标准用于机器学习中的分类和聚类任务,尤其是在语义搜索中。

距离度量传达了两个向量嵌入的相似或不相似程度。

在本文中,我们将探讨各种距离度量,每个度量背后的思想,如何计算它们,以及它们之间的比较。

如果您已经掌握了向量搜索的知识,那么您可以直接跳到 余弦距离部分。

多维空间中的向量

向量数据库通过将每个对象表示为向量嵌入来保留数据的语义含义。每个嵌入是高维空间中的一个点。例如,香蕉(文本和图像)的向量位于苹果附近,而不是猫附近。

Vectors Example

上图是向量空间的视觉表示。要执行搜索,您的搜索查询将被转换为一个向量 - 与您的数据向量类似。向量数据库然后计算搜索查询与向量空间中数据点的集合之间的相似性。

向量数据库速度很快

最重要的是,向量数据库可以 查询大型数据集,包含 数千万或数亿个对象 ,并且仍然在极短的 一小部分秒内 响应查询。

不深入细节,向量数据库如此快速的主要原因之一是它们使用 近似最近邻 (ANN)算法基于向量索引数据。ANN 算法组织索引,以便密切相关的向量存储在一起。

查看这篇文章以了解 “为什么向量搜索如此快速” 以及向量数据库的工作原理。

为什么有不同的距离度量?

根据使用的机器学习模型,向量可以有大约 100 个维度,甚至达到数千个维度。

计算两个向量之间距离所需的时间随着向量维度的增加而增加。此外,某些相似度度量比其他度量更耗费计算资源。这对于计算具有数千个维度的向量之间的距离可能是一个挑战。

因此,我们有不同的距离度量,以平衡计算距离的速度和准确性。

距离度量

余弦相似度

余弦相似度测量多维空间中两个向量之间的角度 - 想法是相似的向量指向相似的方向。余弦相似度常用于自然语言处理 (NLP)。它测量文档之间的相似性,而与幅度无关。

这具有优势,因为如果两个文档通过欧几里得距离相距很远,它们之间的角度仍然很小。例如,如果单词“水果”在一篇文档中出现 30 次,在另一篇文档中出现 10 次,这在幅度上存在明显差异,但如果我们只考虑角度,文档仍然可能相似。角度越小,文档越相似。

余弦相似度和余弦距离具有反比关系。两个向量之间的距离越大,相似度就越小。同样,如果距离减小,则两个向量之间的相似度增加。

余弦相似度的计算公式为

Cosine Similarity

A·B 是向量 A 和 B 的乘积(点积)

||A|| 和 ||B|| 是两个向量的长度

||A|| * ||B|| 是两个向量的叉积

然后 余弦距离 公式为:1 - 余弦相似度

让我们使用一个例子来计算两个水果 - 草莓(向量 A)和蓝莓(向量 B)之间的相似度。由于我们的数据已经表示为向量,我们可以计算距离。

草莓 → [4, 0, 1]

蓝莓 → [3, 0, 1]

Cosine Example

距离为 0 表示向量相同,而距离为 2 表示相反的向量。两个向量之间的相似度为 0.998,距离为 0.002。这意味着草莓和蓝莓密切相关。

点积

点积接受两个或多个向量并将它们相乘。它也被称为标量积,因为输出是一个单个(标量)值。点积显示两个向量的对齐情况。如果向量朝向不同的方向,则点积为负,如果向量朝向相同的方向,则点积为正。

Dot Product direction

点积公式为

Dot Product

使用点积重新计算两个向量之间的距离。

草莓 → [4, 0, 1]

蓝莓 → [3, 0, 1]

Equation 1

两个向量的点积为 13。要计算距离,找到点积的负数。在这种情况下,负点积 -13 报告了向量之间的距离。负点积保持了直觉,即较短的距离意味着向量相似。

平方欧几里得距离 (L2 平方)

平方欧几里得距离 (L2 平方) 通过取向量值的平方和来计算两个向量之间的距离。距离可以是介于零和无穷大之间的任何值。如果距离为零,则向量相同。距离越大,向量之间的距离越远。

平方欧几里得距离公式为

L2 Formula

草莓 [4, 0, 1] 和蓝莓 [3, 0, 1] 的平方欧几里得距离等于 1。

Squared Euclidean  Equation

曼哈顿距离 (L1 范数或出租车距离)

曼哈顿距离,也称为“L1 范数”和“出租车距离”,计算两个向量之间的距离。该度量是通过对两个向量的组件之间的绝对距离求和来计算的。

Manhattan

该名称源于网格布局,类似于曼哈顿的街道。这座城市的设计在每个角落都有建筑物和单行道。如果您试图从 A 点到 B 点,直接穿行是不可能的,因为您无法穿过建筑物。最快的路线是转弯和弯曲较少的路线。

Manhattan example

汉明距离

汉明距离是比较两个数字向量的度量标准。它计算将一个向量转换为另一个向量所需的更改次数。所需的更改越少,向量越相似。

有两种方法可以实现汉明距离

  1. 比较两个数字向量
  2. 比较两个二进制向量

Weaviate 已经实现了第一种方法,即比较数字向量。在下一节中,我将描述一个与二进制通道检索一起使用汉明距离的想法。

让我们使用一个例子来计算汉明距离。想象一下,我们有一个包含各种水果和蔬菜的数据集。您的第一个查询是查看哪种食物最适合您的香蕉煎饼。为了实现这一点,我们需要将香蕉煎饼的向量与其它向量进行比较。就像这样

香蕉煎饼[5,6,8]汉明距离
蓝莓[5,6,9]1
西兰花[8,2,9]3

如上所示,蓝莓是更好的搭配。这是通过比较向量表示食物中数字的位置来实现的。

汉明距离和二进制通道检索

二进制通道检索 (BPR) 将向量转换为二进制序列。例如,如果您有已转换为向量的文本数据(“你好” -> [0.2618, 0.1175, 0.38, …]),然后可以将其转换为 0 或 1 的字符串。虽然它正在压缩向量中的信息,但这种技术即使以 0 或 1 的形式表示,也可以保持语义结构。

要计算两个字符串之间的汉明距离,您需要比较序列中每个位的对应位置。这是通过 XOR 位运算完成的。XOR 代表“异或”,这意味着如果序列中的位不匹配,则输出为 1。请记住,为了执行比较,字符串需要具有相同的长度。以下是比较两个二进制序列的示例。

Hamming and BPR

有三个位置的数字不同(如上图所示)。因此,汉明距离等于 3。Norouzi 等人指出,二进制序列存储效率高,允许在内存中存储海量数据集。

不同距离度量的比较

余弦值与点积

要计算余弦距离,您需要使用点积。同样,点积使用余弦距离来获得两个向量的角度。您可能会想知道这两种度量之间的区别是什么。余弦距离告诉您角度,而点积报告角度和大小。如果您对数据进行归一化,则大小不再可观察。因此,如果您的数据已归一化,余弦值和点积度量完全相同。

曼哈顿距离与欧几里得距离

曼哈顿距离(L1 范数)和欧几里得距离(L2 范数)是机器学习模型中使用的两种度量。L1 范数是通过取向量的绝对值的总和来计算的。L2 范数取向量平方值的平方和的平方根。由于值通常小于欧几里得距离,因此曼哈顿距离计算速度更快。

通常,在曼哈顿距离和欧几里得距离之间选择时,存在准确性与速度的权衡。很难确切地说曼哈顿距离何时比欧几里得距离更准确;但是,由于您不必对差异进行平方,因此曼哈顿距离更快。您希望随着数据维度增加而使用曼哈顿距离。有关在高维空间中使用哪个距离度量的更多信息,请查看 Aggarwal 等人的这篇论文:Aggarwal et al.

如何选择距离度量

作为经验法则,最好使用与您使用的模型匹配的距离度量。例如,如果您正在使用暹罗神经网络(SNN),对比损失函数会包含欧几里得距离。同样,在微调您的句子转换器时,您会定义损失函数。CosineSimilarityLoss 接受两个嵌入并基于余弦相似度计算相似度。

总而言之,没有“一刀切”的距离度量。它取决于您的数据、模型和应用程序。如上所述,在某些情况下,余弦距离和点积是相同的;但是,大小可能重要也可能不重要。这同样适用于曼哈顿距离和欧几里得距离之间的准确性/速度权衡。

使用与您使用的模型匹配的距离度量。

Weaviate 中距离度量的实现

总而言之,Weaviate 用户可以选择五种不同的距离度量来支持他们的数据集。在 Weaviate 文档中您可以详细找到每种度量。Weaviate 使您可以根据您的应用程序轻松选择度量。只需编辑您的模式,您就可以使用 Weaviate 中实现的任何度量(cosinedotl2-squaredhammingmanhattan),或者您可以灵活地创建您自己的!

距离实现和优化

即使使用减少必要的距离计算的 ANN 索引,向量数据库仍然花费大量计算时间来计算向量距离。因此,引擎不仅要正确地执行此操作,而且还要高效地执行此操作非常重要。

Weaviate 中的距离度量已得到优化,使用“单指令多数据”(“SIMD”)指令集,使其高度高效。使用这些指令,CPU 可以在单个 CPU 周期内执行多个计算。为了实现这一点,我们必须用纯汇编代码编写一些距离度量。 这里有一个概述,介绍了当前优化状态;包括哪些距离度量对哪些架构具有 SIMD 优化。

开源贡献

Weaviate 是开源的,重视社区的反馈和投入。一位社区成员通过在 1.15 版本中添加两个新的度量来为 Weaviate 项目做出贡献。这太酷了!如果您对此感兴趣,这里是包含当前度量实现的仓库。

准备开始构建了吗?

请查看 快速入门教程,或使用 Weaviate Cloud (WCD) 的免费试用版构建令人惊叹的应用程序。

不想错过另一篇博文?

注册我们的双周时事通讯以保持更新!


提交后,我同意 服务条款 隐私政策.