1 Introduction
向量检索可以概括为一句话:给定一个查询向量(query),在一堆数据库向量里找出与它最相似的那些向量。这句话里藏着一个必须先回答的问题——什么叫“相似”?
相似度的定义一旦变化,最近邻、可用的算法、结果的语义等等都会变化。举个具体的例子:搜索库里默认用内积(dot product),而另一个库默认用欧氏距离(Euclidean distance),同一份数据、同一个查询,返回的 top-k 可能完全不同。
所以这一篇要做三件事:把常见的度量定义清楚;证明其中几个在什么条件下互相等价;指出它们不等价时会发生什么。
2 Distance and Similarity
一个 \(d\) 维向量可以被视作 \(d\) 维空间里的一个点,也可以想成从原点出发的一支箭头。三个最常用的度量,其实在回答三个不同的问题:
- 欧氏距离:两支箭头的箭尖之间隔多远?
- 内积:一支箭头在另一支方向上的投影有多长?
- 余弦相似度:两支箭头的方向夹了多小的角?
用一句话概括三者的差别:
1 | 欧氏 = 看距离 (长度和方向都算) |
3 Mathematical Definition
设 \(x,y\in\mathbb{R}^d\)。内积定义为
\[ \langle x,y\rangle=\sum_{i=1}^{d}x_i y_i \]
\(\ell_p\) 范数定义为
\[ \|x\|_p=\left(\sum_{i=1}^{d}|x_i|^p\right)^{1/p},\qquad p\ge1 \]
其中 \(p=2\) 是欧氏范数 \(\|x\|_2=\sqrt{\langle x,x\rangle}\),\(p=1\) 是曼哈顿范数。
由此得到对应的距离(\(d_p\) 也叫闵可夫斯基距离):
\[ d_p(x,y)=\|x-y\|_p \]
余弦相似度定义为
\[ \cos(x,y)=\frac{\langle x,y\rangle}{\|x\|_2\,\|y\|_2}\in[-1,1] \]
另外两个来自其他数据形态、但不属于上面这一族的度量(后面讲到稀疏与布尔向量时会用到):
- 汉明距离(Hamming distance):对二进制向量 \(x,y\in\{0,1\}^d\),\(d_H(x,y)=\sum_i[x_i\ne y_i]\),即不同位的个数。
- Jaccard 距离:对集合 \(A,B\),\(J(A,B)=\dfrac{|A\cap B|}{|A\cup B|}\) 是相似度,\(1-J(A,B)\) 是距离。
度量公理
一个函数 \(d\) 要成为严格的距离(度量,metric),必须满足三条:
- 非负性 \(d(x,y)\ge0\) 且 \(d(x,x)=0\);
- 对称性 \(d(x,y)=d(y,x)\);
- 三角不等式 \(d(x,z)\le d(x,y)+d(y,z)\)。\(\ell_p\) 距离(\(p\ge1\))、汉明距离、Jaccard 距离都满足;
余弦相似度不是度量。
4 Normalization
现在假设 \(x,y\) 都是单位向量,即 \(\|x\|_2=\|y\|_2=1\)。那么 \(x,y\) 的欧式距离为:
\[\|x-y\|_2^2=1+1-2\langle x,y\rangle=2-2\langle x,y\rangle.\]
而单位向量下 \(\|x\|_2\ = |y\|_2=1\),所以内积就是余弦:
\[\langle x,y\rangle=\cos(x,y)=1-\tfrac12\|x-y\|_2^2\]
也即是,三个量之间是互相确定的。所以,当所有向量(查询与数据库)都被归一化成单位向量后,内积、余弦、欧式距离相统一。最大内积、最大余弦、最小欧氏距离三种排序完全一致。
这就是向量库惯用“先归一化、再用内积索引”的原因——它可以用最省算的内积实现三种检索语义中的任意一种。
Summary
相似度的定义有三种常见形态——看距离的欧氏、看投影的内积、看朝向的余弦;它们通过 \(\|x-y\|_2^2=\|x\|_2^2+\|y\|_2^2-2\langle x,y\rangle\) 相互关联,在归一化成单位向量后完全等价并可按任意一种检索。