正文
这篇先把三种计算分开:点积把两个向量配合成一个数,范数描述单个向量的大小,距离描述两个向量相差多少。它们能一起用于检索,但不能随意当成同一个概念。
先看点积。假设一个教学用的会议排序规则,给时长、人数和待办数量设置权重。一场会议的特征和权重分别是:
x = [30, 5, 2]
w = [0.1, 1, 2]
x · w = 30 × 0.1 + 5 × 1 + 2 × 2 = 12
中间的圆点表示点积,读作“x 与 w 的点积”。算法很直接:相同位置的数相乘,再把乘积全部加起来。两个实数向量必须使用同一组坐标位置,这个例子才能成立。写成一般公式,就是 x · w = Σ xᵢwᵢ,其中 Σ 表示对所有位置求和。点积与加权求和
结果 12 是我们人为规则下的分数。它没有天然的“百分比”含义,也不能解释成会议有 12 分的价值。改变权重或输入单位,结果就可能改变。机器学习里,权重可以从训练中学到;加权求和的计算形式仍然可以用这个例子理解。
点积还可能是零或负数。例如 [1, 0] 与 [0, 1] 的点积为零,但它们显然不是同一个向量;[1, 0] 与 [-1, 0] 的点积为负,表示两者沿这一方向相反。因此,不能把负分一概当成计算错误,也不能把零分直接理解成没有任何业务关系。计算结果怎样解释,取决于这组坐标原本怎样形成。
再来看范数。为了能在纸上直接计算,我们换成只有两项的向量 a = [3, 4]。想象从平面原点走到坐标 (3, 4),一边走了 3,另一边走了 4,直线长度就是 5。由此得到常见的 L2 范数,也叫欧几里得范数:
||a||₂ = √(3² + 4²) = 5
两条竖线表示范数,右下角的 2 说明使用哪种计算规则。对更多坐标,也是把每项平方、相加,再开平方。它把向量的多个数压缩成一个非负的大小指标。
范数有不止一种。对同一个 a,L1 范数是 |3| + |4| = 7:先取每项的绝对值,再求和。绝对值表示忽略正负号后的大小。负数也能参与,例如 [-3, 4] 的 L1 范数仍然是 7,L2 范数仍然是 5。常用向量范数的定义
“向量长度”有时指坐标数量,有时指范数,读文档时要看上下文。 [3, 4] 有两个坐标,L2 范数为 5;不能因为有两个数,就说它的 L2 范数也是 2。这里的长度也没有自动对应文字长度:一篇长文的向量,范数未必大于一篇短文的向量。
有了范数,就可以计算距离。把两个向量对应位置相减,得到差向量,再求它的范数。例如:
a = [3, 4]
b = [0, 0]
a - b = [3, 4]
欧几里得距离 = ||a - b||₂ = 5
曼哈顿距离 = ||a - b||₁ = 7
欧几里得距离可以理解成平面上的直线距离,曼哈顿距离可以类比沿两条坐标方向走的总路程。推广到高维以后,通常画不出实际路线,但相应的数值计算仍然清楚。
距离越小,只能说明在当前坐标表示和当前计算规则下越接近。如果把会议的“分钟”改成“秒”,某一坐标的差异就会放大很多,距离也会被它影响。不同特征的单位、尺度和重要程度,需要在建模时处理。涉及从数据估计缩放参数时,后面还要遵守训练和评估的隔离规则。
知识库常用的余弦相似度,则把点积和范数结合起来。对两个非零实数向量:
cos(a, b) = (a · b) / (||a||₂ × ||b||₂)
先点积,再除以两个向量的 L2 范数乘积,结果位于 -1 到 1。可以先理解为:比较它们朝向是否接近,减少整体长短对结果的影响。同向是 1,互相垂直是 0,完全反向是 -1。这里讨论的是一般实数向量;具体 Embedding 模型的分数分布还要看实际表示。向量空间检索中的余弦计算
我们做一个很小的假设例子。问题向量 q = [1, 2],三个候选文档向量如下。它们是手写数字,仅用于说明运算,不是实际模型生成的 Embedding。
| 候选 | 向量 | 与 q 的点积 | 与 q 的余弦相似度 |
|---|---|---|---|
| A | [2, 1] | 4 | 0.8 |
| B | [20, 10] | 40 | 0.8 |
| C | [0, 3] | 6 | 约 0.894 |
B 恰好是 A 的十倍。它和问题的点积扩大了十倍,余弦相似度却保持一样,因为朝向没有改变。按照点积降序,顺序是 B、C、A;按照余弦降序,C 排在前面,A 与 B 相同。选择哪种计算规则,会影响候选排序。
再看距离,q 到 A 的欧几里得距离是 √2,到 B 是 √425。虽然 A、B 的余弦分数相同,它们到 q 的距离差别却很大。余弦主要比较方向,原始欧几里得距离还受大小影响。不存在一个规则,在所有表示和所有任务里都自动更好。
还有一个选择背后的问题:向量的大小有没有携带我们需要的信息?如果模型训练时让范数也参与表达匹配程度,盲目归一化可能丢掉有用信号;如果任务希望忽略整体倍数,余弦可能更符合目标。因此,先依据 Embedding 模型说明和检索目标确定规则,再通过有标准答案的查询集比较效果。仅凭“大家都用余弦”不足以决定一套检索系统的计算方式。
如果先把非零向量除以自己的 L2 范数,就得到了单位范数向量,这个操作常叫 L2 归一化。此时,两向量的点积等于它们的余弦相似度。对于都归一化后的向量,还成立:
欧几里得距离的平方 = 2 - 2 × 余弦相似度
这意味着在这些前提下,用最小欧几里得距离和用最大余弦相似度,得到的理论排序一致。它没有说明任意原始向量都能直接互换规则,也没有消除近似检索、数值误差或并列分数带来的实际差异。
零向量需要单独注意。[0, 0] 的范数是 0,放入余弦公式会造成除以零。系统必须定义处理办法,例如拒绝这个输入或给出明确的特殊值,不能把它解释成一个正常的方向。某些程序还会用小量防止数值问题,具体返回值需要查看实现。
还要区分“相似度”和“距离”的排序方向。相似度常常越大越相近,距离常常越小越相近。一些检索接口返回的字段叫 score,但内部可能是距离,也可能是经过变换的分数。只看字段名称,容易把最不相近的结果放到最前面。常见的 1 - 余弦相似度也被称为余弦距离,但它一般不满足数学距离的全部条件,不能据此套用所有距离定理。
这些计算最终服务的是任务。问题“会议改期到哪一天”与一篇反复出现“会议改期”的旧通知,向量可能很相近;它却可能不是这次会议的资料。检索系统仍然需要日期、权限、文档版本和内容核验。相似度分数也不自动是“答案正确的概率”,0.9 的相似度不能直接读成 90% 的事实可信度。
如果你以后调试一次知识库检索,先确认三个条件:问题和文档是否使用兼容的表示;有没有按模型要求归一化;返回的分数究竟代表什么。接着才用任务标注判断排序是否有效。这样,点积、范数与距离就从纸上的公式,变成了可以检查系统行为的工具。
当前学习编号:03.02 点积、范数与距离。
下一学习编号:03.03 矩阵秩与低秩分解。后续还有其他学习编号。
关联分支:数值结构对应 03.01 向量、矩阵与张量;输入尺度和预处理边界,对应 04.07 特征工程、06.14 预处理仅在训练部分拟合;检索表示和分数使用,对应 15.03 稠密向量与 Embedding 模型、15.04 余弦相似度与向量距离、15.11 候选召回与 Top-k、15.19 相似度、相关性与真实性的区别;模型中的点积运算,对应 08.06 注意力机制、08.07 Query、Key、Value。