嵌入(Embedding)

嵌入把文本等对象编码成数值向量,使程序能够计算它们的相似程度。向量表示有助于检索,但相似并不等于事实相同。

返回概念图谱 →

理解与应用

嵌入是一种把对象表示为数值向量的方法。在文本检索中,编码模型把句子或文档映射到一组数字,查询也经过相应编码;程序随后比较向量之间的距离或相似度。训练会影响哪些对象在这个空间里接近,因此向量通常不能靠逐个数字直接读出一句话的含义。

例如员工问“酒店钱能报多少”,文档写的是“住宿费用标准”。两者用词不同,但与报销住宿相关,适合文本检索的嵌入模型有机会把它们放到相近位置。不过,“可以报销住宿费”和“不可以报销住宿费”也围绕同一主题,可能同样接近。向量能够帮助寻找候选,是否满足问题仍要阅读原文中的否定、日期和适用条件。

相似度的计算方法也会影响排序。余弦相似度比较方向,点积还受到向量长度影响;把向量归一化为单位长度后,点积与余弦值相同。实际使用哪一种,应与编码模型的训练方式和索引设置一致,不能只因为某个数值看起来更大就认为检索更好。

向量通常需要由兼容的模型和配置生成。更换编码模型后,即使维度相同,新旧坐标也未必可比较,往往需要重新编码资料并验证检索结果。选择模型时,中文、领域术语、文档长度和任务类型都比单看维度更有意义;保存模型版本和原文来源,才能在结果异常时追查表示是怎样生成的。

关系速览
嵌入(Embedding)建议先学 →向量检索

学习建议:先理解向量表示与相似度,再分析向量检索的召回误差。

动手试一试:余弦与点积为什么可能给出不同偏好

这些是手工设置的二维向量,不是文本编码结果。同方向的两个向量余弦相同,点积却随长度改变。这个几何差异解释了为什么编码模型、归一化方式和检索度量需要配套。

将代码保存为 example.py,使用 Python 3.10+ 运行 python3 example.py。仅使用标准库,无需密钥,不会调用外部模型。

Python 代码

from math import sqrt

query = (1.0, 0.0)
vectors = {
    "同方向,长度1": (1.0, 0.0),
    "同方向,长度3": (3.0, 0.0),
    "偏离45度": (1.0, 1.0),
}

def dot(a, b):
    return sum(x * y for x, y in zip(a, b))

def norm(v):
    return sqrt(dot(v, v))

for name, vector in vectors.items():
    cosine = dot(query, vector) / (norm(query) * norm(vector))
    print(f"{name}: 点积={dot(query, vector):.1f},余弦={cosine:.3f}")

运行结果

同方向,长度1: 点积=1.0,余弦=1.000
同方向,长度3: 点积=3.0,余弦=1.000
偏离45度: 点积=1.0,余弦=0.707

常见误区

  • 把高度相似的向量当成内容一致的证明,可能漏掉否定词、版本或生效日期的差别。
  • 混用不同编码模型产生的向量,即使它们长度相同,也可能使相似度失去可解释性。

前置与延伸

建议先读

相关概念

参考与版本

Apollo 原创讲解与教学示例。参考资料用于核对技术定义;核验日不代表资料的发布日期。