在 AI 检索系统的搜索框里输入「怎么退订会员」,第一条返回「取消自动续费的方法」。两句话没有一个词重合,系统却认定它们高度相关。这类匹配靠的是把文本变成向量后比较方向,常用度量是余弦相似度。它和欧氏距离常被一起讨论,因为两者回答的是不同问题:一个问朝哪个方向,一个问隔多远。选错了,检索结果会明显变差。下面用五组对照讲清分工,再说三个实际会踩的坑。
同一批向量,两种问法
把每段文本压成几百维的向量,每一维代表某种语义倾向。余弦算的是两个向量夹角的余弦:方向一致时接近 1,垂直时为 0,方向相反时接近 -1。它只关心方向,一段话重复两遍,向量长了一倍,相似度仍是 1。欧氏距离算两点之间的直线长度,长度直接进结果,同样的意思写成长短两版,距离明显拉开。两个定义只差一个归一化,实际影响的却是「什么算相似」这个判断。
五组对照
| 对比维度 | 余弦相似度 | 欧氏距离 | 谁更合适 |
|---|---|---|---|
| 衡量什么 | 两个向量的夹角 | 两点之间的直线长度 | 看语义用前者,看绝对差异用后者 |
| 是否受长度影响 | 不受,长向量短向量一视同仁 | 受,长度差会直接抬高数值 | 文本偏向余弦,测量数据偏向欧氏 |
| 取值范围 | 负一到一,有明确上下界 | 零到正无穷,随量纲变化 | 需要统一阈值时余弦更好设 |
| 计算开销 | 点积加两个模长,归一化后只剩点积 | 逐维求差、平方求和再开方 | 大规模检索里余弦更容易优化 |
| 零向量 | 没有方向,结果无定义 | 照常可算 | 余弦必须先过滤空向量 |
第三行常被忽略。余弦固定在负一到一之间,「相似度大于 0.8 就召回」这类阈值可以跨数据集沿用;欧氏距离随维度和量纲变化,同一个阈值换个场景就失效。第四行解释工程上为什么偏爱余弦:归一化后余弦等于点积,点积可以预先建索引,把逐个比较变成近似最近邻查找,这是向量检索撑住亿级数据的前提,机制见 向量数据库。
文本为什么天然偏向余弦
文本向量的长度往往和写了多少相关。词频统计的年代,长文档的向量模长天然更大,直接算欧氏距离,长文档会被判为和谁都不像。余弦把模长除掉,把说了多少和说了什么分开。这个传统延续到 词嵌入 时代:嵌入向量的方向承载语义,模长更多反映词频或置信度,用余弦更贴合设计。检索增强生成的召回也沿用这套做法,RAG 的召回质量很大程度上取决于向量和度量是否匹配。
什么时候欧氏距离更对
当各维度量纲一致、数值差距本身有意义时,欧氏距离更自然。地理位置、传感器读数、同一指标下的用户画像都属于这类:两点相距多远,这个「多远」可以解释成实际差距。近邻方法默认用它,假设特征空间里的邻近就代表相似。用欧氏距离前通常要标准化,否则量纲大的维度会独占权重,以元为单位的字段动辄上千,会把其他维度盖住。余弦虽不看整体长度,但各维度的相对大小同样改变方向,缩放没做好一样会偏。
三个容易踩的坑
第一个是没归一化就混用两种度量。召回用余弦、排序用欧氏,尺度不同,融合时权重失真。第二个是零向量。空文本、全是停用词会得到接近零的向量,余弦分母趋近于零,结果要么报错要么是噪声,入口必须过滤。第三个是维度灾难:维度越高,随机两点距离越接近,最近邻与次近邻的差距被压缩,欧氏距离的区分力下降,余弦好一些,但也没免疫。
它衡量不了的那部分
余弦只看方向,看不懂否定和语序。「我喜欢这个方案」和「我不喜欢这个方案」在词袋向量里可能高度相似,关键词几乎一样。它也无法区分相关和正确:一段话和问题语义接近,不代表它能回答问题。对嵌入质量的依赖是另一条硬边界,模型没见过领域术语时,方向和语义对不上,再精确的度量也救不回来。工程上的常规做法是混合检索:向量召回管语义相近,关键词召回管精确命中,重排模型做最后判断。分类场景下另一种基于距离的做法,可以看 KNN。
给普通人的判断
看到「相似度 0.92」这种数字,先问它算的是什么、向量怎么来的、有没有归一化。同一个 0.92 在不同模型、度量下含义可能差很远。评估检索产品时尤其要追问:演示例子往往挑得很好,真正决定体验的是长尾查询,而长尾最容易失真。
速查:余弦与欧氏
- 余弦问方向:夹角越小越像,与长度无关
- 欧氏问距离:直线越短越近,长度直接影响结果
- 文本检索偏余弦:把说了多少和说了什么分开
- 数值比较偏欧氏:量纲一致、绝对差距有意义时用它
- 两个硬坑:零向量无定义,缩放没做好就会偏


