嵌入 Embedding
约 1372 字大约 5 分钟
2026-06-28
嵌入(Embedding)是一种寻找词与词之间相似性的 NLP 技术。它把词在各个维度上的特征用数值向量表示,靠这些维度上的相似程度,就能判断哪些词语义更接近。
前面说过,一段文本经过分词器处理后,会变成一串词元 ID:
| 词语 | 词元 ID |
|---|---|
| 我 | 1001 |
| 喜欢 | 1002 |
| 小猫 | 2001 |
| 和 | 1003 |
| 小狗 | 2002 |
到这一步,模型看到的还只是一堆编号,没有任何语义信息——它不知道 "小猫" 和 "小狗" 其实很像。嵌入要做的,就是给这些词元注入语义。
工作原理
做法是引入一个 嵌入矩阵(embedding matrix),为每个词元配一条向量。这条向量是 高维 的,实际能到成百上千维,每一维代表一个语义方向。
这里简化成 4 维,看 "小猫" 这条向量怎么理解:
| 向量维度 | 隐含的语义方向 | 小猫的值 | 粗略含义 |
|---|---|---|---|
| 第 1 维 | 是否是动物 | 0.72 | 是动物,得分高 |
| 第 2 维 | 亲和力 / 可爱度 | 0.35 | 稍微可爱 |
| 第 3 维 | 体型大小(抽象) | 0.11 | 比较小 |
| 第 4 维 | 家养 vs 野外 | 0.80 | 更偏向家养 |
于是词元就嵌入了向量值:
| 词元 ID | 词语 | 嵌入向量(4 维) |
|---|---|---|
| 2001 | 小猫 | [0.72, 0.35, 0.11, 0.80] |
| 2002 | 小狗 | [0.70, 0.38, 0.14, 0.78] |
| 1002 | 喜欢 | [0.10, 0.93, 0.21, 0.11] |
现在 "小猫" 和 "小狗" 不再是冷冰冰的 ID,而是 两条很接近的向量——模型会把它们当成相似概念处理。而 "喜欢" 这条向量在数值上离得明显更远。
如果把高维向量投影到二维平面来可视化,语义相近的词会聚得更近:

- "小猫" 和 "小狗"这类意思相近的词,靠得更近
- "喜欢" 这种语义不同的词,离它们稍远
- "讨厌"、"桌子" 这类不相关的词,离得更远
向词元嵌入向量,带来四个关键好处:
- 传递语义相似性 —— 相似的词向量靠近
- 支持上下文学习 —— 嵌入可在训练中更新
- 可参与数学运算 —— 词向量支持加减
- 可输入神经网络 —— 向量能计算梯度
正是 "可参与数学运算" 这一点,让从 词袋模型 起就追求的 "文本向量化" 真正有了语义——词袋只统计词频,嵌入则把语义压进了向量本身。
Word2Vec
Word2Vec 即 Word to Vector(词 → 向量)。2013 年,托马斯·米克洛夫和他在 Google 的同事提出了这个算法。它用一种高效的方式学习词的连续向量表示,把词汇表里每个词都表示成 固定长度 的向量,从而让大规模数据集上的训练变得可行。

Word2Vec 有两种思路截然相反的训练方式:
CBOW 模型
核心思想:给定一个词的 上下文(前后词),预测 中心词。
我 喜欢 吃 苹果输入上下文("我","吃"),模型预测出中心词 "喜欢"。
Skip-Gram 模型
核心思想正好反过来:给定 中心词,预测它的 上下文词。
我 喜欢 吃 苹果输入中心词 "喜欢",模型预测出上下文 "我" "吃"。
两者对比
| 比较项 | CBOW | Skip-Gram |
|---|---|---|
| 训练目标 | 预测中心词 | 预测上下文 |
| 输入 | 上下文词(多个) | 中心词(一个) |
| 输出 | 中心词(一个) | 上下文词(多个) |
| 训练速度 | 快 | 慢 |
| 稀有词表现 | 一般 | 更好 |
| 语义表达能力 | 差一些 | 更强 |
| 适合场景 | 大词频、高效率、短上下文 | 稀有词、多语义任务、大语料 |
训练时二选一即可,在代码里通过 sg 参数指定:
sg=0使用 CBOWsg=1使用 Skip-Gram
重要含义
嵌入把词元 ID 升级成带语义的高维向量,让 "语义相似 = 向量相近" 成立,这是 词袋模型 解决不了的核心问题。Word2Vec 用 CBOW / Skip-Gram 两种互为反向的任务高效学出这些向量,是词嵌入的奠基之作。理解了嵌入,才能顺势理解后面 Transformer 里的位置编码与注意力——它们处理的都是这种向量。
代码实践
用 gensim 训练一个最小可跑的 Word2Vec。先训练并保存模型:
from gensim.models import Word2Vec
# 示例语料(已分好词)
sentences = [
["i", "love", "deep", "learning"],
["i", "love", "nlp"],
["deep", "learning", "is", "fun"],
["nlp", "is", "a", "part", "of", "ai"],
["word2vec", "is", "a", "powerful", "embedding"],
]
# 训练模型:vector_size 向量维度,window 上下文窗口,sg=1 用 Skip-Gram
model = Word2Vec(sentences, vector_size=100, window=2, min_count=1, sg=1)
# 保存模型
model.save("word2vec.model")
print("模型训练完成并已保存。")再加载模型,看词向量、找相似词、算相似度:
from gensim.models import Word2Vec
# 加载模型
model = Word2Vec.load("word2vec.model")
# 获取某个词的词向量
print("词向量(nlp):")
print(model.wv["nlp"])
# 找出最相似的词
print("\n与 'nlp' 最相似的词:")
print(model.wv.most_similar("nlp", topn=3))
# 计算两个词的相似度
print("\n'deep' 和 'learning' 的相似度:")
print(model.wv.similarity("deep", "learning"))提示
这个例子语料极小,相似度数值没有实际意义,只用于跑通流程。真实训练需要大规模语料,Word2Vec 才能学出有意义的语义关系。
