How Do Word Embeddings Capture Relationships Between Words?
TL;DR · AI 摘要
词嵌入通过向量空间中的几何关系捕捉词语间的语义关联,是NLP中实现语义理解的关键技术。
核心要点
- 词嵌入将词语映射为向量,通过向量距离反映语义相似性
- Word2Vec和GloVe是主流词嵌入模型,能捕捉同义词/反义词关系
- 现代LLM和RAG系统依赖词嵌入实现语义检索与生成
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- 词嵌入与语义关系
- 基础概念
- 向量表示方法
- Word2Vec/GloVe模型
- 关系捕捉
- 向量距离表征相似性
- 几何关系建模
- 现代应用
- LLM输入处理
- RAG系统实现
金句 / Highlights
值得收藏与分享的关键句。
词嵌入通过向量空间中的几何关系捕捉词语间的语义关联
现代搜索系统结合关键词匹配、嵌入和排序模型实现语义检索
RAG技术利用嵌入实现基于语义的信息检索与生成
Word Embeddings 如何捕捉词语之间的关系?| Towards Data Science
NLP
Word Embeddings 如何捕捉词语之间的关系?
理解词语如何在学习到的向量空间中建立关联
Nikhil Dasari
2026年10月14日
14分钟阅读
在Google上关注我们
分享
词嵌入与词语关系的概念示意图。位置仅为示例,非实际嵌入坐标。图片由作者创作。
欢迎回来!
让我问你一个问题。
你每天走路吗?还是每天锻炼?
我们的生活变得越来越忙碌,与过去相比,生活方式发生了很大变化。
但,我们仍然试图抽出一些时间定期走路或锻炼以保持健康。
我也决定将跑步作为我日常生活中的一部分。
照片由 David Kanigan 拍摄:https://www.pexels.com/photo/morning-jog-at-sunrise-in-stamford-park-28735804/
当我们想到走路或跑步时,首先想到的是鞋子。
我也想买一双好的跑步鞋。
如果某样东西可以在网上找到,我们通常更倾向于在线购物,因为我们可以花时间比较不同的产品并选择自己想要的。
因此,我也决定在网上购买我的鞋子。
我打开了购物应用并搜索了“跑步鞋”。
图片由作者创作
我看到了来自不同公司的各种鞋子,但我注意到一个有趣的现象。
许多鞋子被描述为“跑步鞋”,而其他鞋子则被描述为“走路鞋”、“运动鞋”、“运动休闲鞋”等。
但我的搜索词仅仅是“跑步鞋”。
于是,我心中产生了一个问题:
这个应用是如何知道“跑步鞋”和“运动鞋”是相关的,尽管它们是不同的词语?
在试图理解这个问题时,我接触到了一个叫做词嵌入的概念。
···
购物已完成。现在让我们理解发生了什么。
在开始我们的探索之前,我还想补充一点:嵌入在现代AI中的重要性。
大型语言模型(LLMs)在处理输入时,例如我们的提示,也会使用嵌入。
你可能也注意到AI助手有时可以从网络或其他来源检索相关信息,并利用这些信息生成响应。
这种方法通常被称为检索增强生成(Retrieval-Augmented Generation,简称RAG)。
当然,现代搜索系统可能会结合不同的技术,例如关键词匹配、嵌入和排序模型。
然而,嵌入通过帮助系统识别语义关系并基于含义而非仅仅依赖精确的词语匹配来检索信息,在许多现代AI应用中发挥着重要作用。
什么是词嵌入,为什么我们需要它们?
简单来说,嵌入是对某物的数值表示。
在词嵌入的情况下,一个词被表示为一组数字向量。
你可能会疑惑,我们在之前的TF-IDF博客中已经做过类似的事情。
让我们回顾一下上一篇博客中TF-IDF的处理方式。
我们考虑了一些句子,并希望将它们分类为正面或负面。
为此,我们使用TF-IDF方法将句子转换为数值表示。
但我们是基于这些文档中词语的重要性来表示文本,而不是根据每个词的上下文学习其独立的表示。
如果我们观察 TF-IDF,它主要是一种统计方法。它依赖于诸如某个术语在文档中出现的频率,以及该术语在整个文档集合中是常见还是罕见等因素。
但在词嵌入的情况下,情况有所不同。
在这里,我们的目标是根据词语与其他词语的使用方式,为每个词语学习一种向量表示。
我们试图从数据中学习词语之间的关系。
模型如何学习词语之间的关系?
我们所说的“学习到的向量表示”是什么意思?学习是如何发生的?
让我们通过一个简单的例子来清楚地理解这一点。
假设我们想要为一个在线购物网站构建一个搜索系统。
正如我们之前讨论的,如果我们搜索“跑步鞋”,目录中可能有产品被描述为“慢跑鞋”、“运动鞋”或类似的内容。
如果系统只寻找完全匹配的词语,可能会错过一些相关产品。
因此,我们希望系统能够学习到在相似上下文中出现的词语是相关的。
但我们不希望手动创建一个字典来说明哪些词语相关、哪些不相关。
相反,我们希望系统能够从文本本身中学习这些关系。
为了理解学习过程是如何工作的,让我们考虑几个句子。
- 美味的食物被端上了桌。
- 我享受了那顿美味的餐食。
- 那家餐厅提供美味的食物。
- 新车配备了一个强大的发动机。
- 大卡车配备了一个强大的发动机。
现在我们有5个句子。这就是我们的简单数据集。
在这里,我们的目标是理解嵌入是如何学习的,即如何根据词语出现的上下文将词语表示为向量。
在这里,我们希望理解词嵌入背后的详细数学原理,因此我们使用了一个简单的数据集。
现在,通过观察这五个句子,我们能说什么?
我们可以认识到“食物”和“餐食”是相关的。
同样,从最后两个句子中,我们可以认识到“汽车”和“卡车”是相关的,因为它们也出现在相似的上下文中。
但机器不会自动知道这些关系。
我们需要机器从文本中学习这些关系。
首先,让我们看一下数据集中独特的词语。
在将所有词语转换为小写并去除重复词语后,我们词汇表中共有19个独特的词语。
现在,为了找到词语之间的关系,我们需要将每个词语数值化表示。
这意味着我们需要为词汇表中的每个词语提供一种向量表示。
Word2Vec 如何从上下文中学习?
学习词嵌入的一种流行技术是 Word2Vec。
它有两种架构:一种是 Skip-gram,另一种是 CBOW(Continuous Bag Of Words)。
在本文中,我们首先关注 Skip-gram。
为了理解 Skip-gram 是如何工作的,让我们考虑数据集中的一个句子:
' 美味的食物被端上了桌。 '
接下来,我们从句子中选择一个词作为“目标词”。
让我们选择“食物”作为我们的目标词。
接下来,我们选择一个上下文窗口。
例如,如果我们设置上下文窗口为 1,我们考虑目标词左右各一个词作为上下文词。我们将这些词称为上下文词。
在这里,让我们将上下文窗口设置为 1。
然后,我们有:
对于目标词“食物”,我们有上下文词“美味”和“被”。
在这里,“目标词”指的是我们试图为单词“food”学习一个数值表示。为此,我们首先查看目标词出现的上下文,使用一个上下文窗口。
在我们的示例中,目标词“food”与两个上下文词“tasty”和“was”一起出现。
由此,我们可以创建两个目标-上下文对:(food, tasty) 和 (food, was)。
现在,这些对将作为我们Skip-gram模型的训练示例。
现在问题是,Skip-gram实际上如何处理这些对?
Skip-gram会使用目标词,并尝试预测出现在它周围的上下文词。
例如,我们有一个对(food, tasty)。我们将food输入模型,并要求它预测tasty。
通过这样做,模型会从文本中的模式中学习哪些词倾向于彼此出现。
这在一开始可能会有些令人困惑,但一旦我们通过一个示例进行分析,就会变得清晰。
但Skip-gram如何根据目标词预测上下文词?
让我们来看。
词语如何表示为向量?
在这里,我们希望为每个单词找到嵌入(embedding),这是该单词的已学习数值表示。
我们的词汇表中有19个唯一单词,这意味着我们需要为每个单词学习一个嵌入。
但首先,我们需要决定嵌入的维度。
如果我们选择嵌入维度为2,那么每个单词将由一个二维向量表示。
例如,food的初始嵌入如下:
$$ v_{food} = [0.2,\;0.7] $$
在训练开始时,我们使用随机值初始化每个单词的嵌入值。
这些值将在训练过程中被更新。
现在,我们有19个唯一单词,每个单词都有一个二维嵌入。因此,我们的嵌入矩阵的形状将是:
$$ W \in \mathbb{R}^{19 \times 2} $$
其中,W是嵌入矩阵,R表示实数集合。
它看起来像这样:
$$ W = \left[ \begin{array}{c} \mathrm{embedding\ of\ the}\\ \mathrm{embedding\ of\ tasty}\\ \mathrm{embedding\ of\ food}\\ \mathrm{embedding\ of\ was}\\ \vdots\\ \mathrm{embedding\ of\ truck} \end{array} \right] $$
当我们为所有单词初始化嵌入时,模型需要一种方式来知道哪个单词对应于嵌入矩阵的哪一行。
为此,我们可以使用基于词汇表中位置的独热向量(one-hot vector)来表示每个单词。
例如,考虑food,目前它是我们的目标词,
它的独热表示是:[0,0,1,0,.......,0]
其中的1告诉我们food在我们的词汇表中的位置。
然后模型可以使用这个位置从嵌入矩阵中检索对应的行。
因此,如果我们的嵌入矩阵的第三行是:[0.2, 0.7]
那么模型将检索到:
这个从嵌入矩阵中检索与某个单词对应的向量的过程称为嵌入查找(embedding lookup)。
在实际应用中,实现通常使用单词的整数ID直接检索对应的行,而不是构建完整的独热向量。
嵌入维度
在继续之前,让我们首先讨论嵌入维度。
在我们的示例中,我们选择嵌入维度为2,因为它使数学计算保持简单,并且对我们理解过程非常容易。
但在实际应用中,嵌入维度可以大得多。
例如,根据模型和应用的不同,可以使用 100、300、512、768、1024、1536 甚至更大的值作为维度。
假设我们选择了一个 300 的嵌入维度。
那么,300 的嵌入维度究竟意味着什么呢?
我们已经知道,每个词现在由一个包含 300 个数值的 300 维向量表示。
从数学角度来看,我们可以将其视为一个 300 维空间中的点,或者说是具有 300 个坐标轴的坐标系中的一个点。
这时,一个疑问浮现出来。
这 300 个坐标轴究竟代表什么呢?
通常,学习到的词嵌入维度对人类来说并没有直接可解释的含义。
我们通常不会看到类似这样的定义:
维度 1 = "与食物相关"
维度 2 = "情感"
维度 3 = "大小" 等等。
例如,假设我们的词汇表包含 10,000 个词。
在大型语料库中,我们可能会发现与句法、语义关系、主题和词使用相关的模式。
这些信息可以分布在许多维度中,模型会从训练数据中的模式中学习这些维度的数值。
如何选择嵌入维度?
嵌入维度是一个超参数。
在实践中,我们可以尝试不同的值,并评估生成的嵌入在我们想要完成的任务中的表现。
选择也可能取决于训练数据的大小、计算资源和问题的复杂性等因素。
因此,并没有一个普遍适用的“正确”嵌入维度。
更大的维度可以提供更强的模式表示能力,但也会增加参数数量、内存需求和计算成本。
随着我们进入更高级的概念,我们将更好地理解嵌入维度是如何被选择的。
在选择了嵌入维度之后,我们需要为词汇表中的每个词用随机值初始化嵌入。
这意味着我们要初始化 19 个目标词的嵌入,每个词对应一个。
在训练过程中,每个词都可能成为目标词,其嵌入会根据训练样例进行更新。
让我们看看具体是如何进行的。
这里,我们选择了 2 作为嵌入维度,现在让我们关注当前目标词 food。
让我们初始化 food 的嵌入。
对于 food,我们已经有两个目标-上下文对:(food,tasty) 和 (food,was)。
在这里,我们可能会混淆上下文窗口和嵌入维度的概念。它们是两个不同的概念。
上下文窗口决定了哪些邻近词被视作上下文词,而嵌入维度决定了每个词使用多少个数值来表示。
我们已经初始化了目标词 food 的嵌入,现在我们有两个上下文对。
现在我们该怎么做?
让我们先考虑一个目标-上下文对:(food,tasty)
我们希望模型学习到 tasty 是 food 的上下文词。
这意味着什么?
我们已经有了 food 的数值表示。
为什么 Word2Vec 使用两组向量?
现在,模型需要一种方式来表示 tasty 作为可能的上下文词,从而学习到 food 和 tasty 在这个上下文中是相关的。
为此,我们需要 tasty 的上下文/输出向量。
就像我们为词汇表中的所有词初始化目标/输入嵌入一样,我们同样为词汇表中的所有词用随机值初始化上下文/输出向量。
因此,在 Skip-gram 训练过程开始时,我们有两组向量:
19 个目标/输入向量,每个词汇表中的单词对应一个向量,
19 个上下文/输出向量,每个词汇表中的单词对应一个向量。
总计,我们的简化示例有 38 个向量。
我们可以认为 Skip-gram 在训练过程中使用这两组不同的向量。
现在,让我们看一下显示目标/输入词和上下文/输出词初始化词向量的表格。
对于我们的目标-上下文对 (food, tasty),我们有 food 的初始化目标/输入向量和 tasty 的初始化上下文/输出向量。
0.4
0.8
u_{tasty} = [0.4,\;0.8]
我们用 v 表示目标/输入向量,用 u 表示上下文/输出向量。
Word2Vec 如何对目标-上下文对进行评分?
仅仅拥有这些向量还不够。
我们需要衡量当前目标向量和上下文向量对这个特定目标-上下文对的支持程度有多强。
这就是我们使用点积的地方。
我们已经知道,方向相似的向量通常具有较大的点积,而方向不同的向量通常具有较小或负的点积。
让我们计算点积:
⋅
(
)
+
0.08
0.56
0.64
$$ v_{food} \cdot u_{tasty} = (0.2)(0.4) + (0.7)(0.8) = 0.08 + 0.56 = 0.64 $$
我们现在为 (food, tasty) 这个对得到了 0.64 的评分。
为什么点积本身不够?
但仅凭这个评分,模型还无法判断 tasty 是否是 food 的合适上下文词。
我们需要将其与其他评分进行比较,才能了解它在这些评分中的相对位置。
由于我们的词汇表包含 19 个词,我们需要计算目标向量 food 与词汇表中每个词的上下文/输出向量之间的点积。
这会给我们 19 个评分,每个可能的上下文词对应一个评分,我们可以用这些评分来比较,以确定模型当前认为哪些词更可能出现在 food 的上下文中。
现在,我们已经为词汇表中所有 19 个词计算了点积评分。
但如何利用这些评分来帮助模型学习有用的词表示呢?
对于我们的目标-上下文对 (food, tasty),我们希望模型在接收到 food 作为目标词时能够学习预测 tasty。
然而,模型的向量是随机初始化的,因此尚未学习到词语之间的有意义关系。
如果我们查看点积评分,可以观察到 tasty 获得了最高评分。
但这纯粹是巧合,因为这些评分是使用随机初始化的向量计算得到的。
我们不应该假设模型已经知道 tasty 是 food 的正确上下文词。
此时,我们可能会认为应该训练模型以提高 tasty 的点积评分。
但有一个重要的问题需要考虑。
food 的目标向量用于计算所有候选上下文词的评分。
在训练过程中,当我们更新这个目标向量时,它与多个上下文向量的点积可能会发生变化。
我们可能会想,如果其他点积评分增加或减少怎么办?我们只希望提高 tasty 的评分,对吗?
然而,仅仅提高正确词的评分并不能告诉我们模型是否已经学会了更好地将其与其他选项区分开来。
我们希望模型在给定 food 的情况下,将 tasty 的概率分配得比其他上下文词更高。
这是我们需要概率的地方。
概率帮助我们理解模型如何在上下文词之间分配其预测结果。
对于我们的目标-上下文对(food, tasty),我们希望模型为tasty分配更高的概率,因为它是这个示例的正确上下文词。
但如何将点积得分转换为概率呢?
这时Softmax函数就派上用场了。
Softmax如何将得分转换为概率?
Softmax将点积得分转换为0到1之间的概率,所有概率之和为1。
以下是公式:
P
∣
exp
∑
1
P(w_O \mid w_I) = \frac{\exp(u_{w_O}^{T}v_{w_I})} {\sum_{w=1}^{V}\exp(u_w^{T}v_{w_I})}
其中:
:
给定目标词的上下文词概率
目标词或输入词
我们想要预测的实际上下文词
目标词的输入/目标向量
候选词的输出/上下文向量
两个向量的点积
x
指数函数
词汇表中唯一词的总数
词汇表中所有词的点积得分的指数和
\begin{aligned} P(w_O \mid w_I) &:\ \text{给定目标词 } w_I \text{ 的上下文词 } w_O \text{ 的概率} \\[8pt] w_I &:\ \text{目标词或输入词} \\[8pt] w_O &:\ \text{我们想要预测的实际上下文词} \\[8pt] v_{w_I} &:\ \text{目标词的输入/目标向量} \\[8pt] u_{w_O} &:\ \text{候选词的输出/上下文向量} \\[8pt] u_{w_O}^{T}v_{w_I} &:\ \text{两个向量的点积} \\[8pt] \exp(x) &:\ \text{指数函数 } e^x \\[8pt] V &:\ \text{词汇表中唯一词的总数} \\[8pt] \sum_{w=1}^{V}\exp(u_w^{T}v_{w_I}) &:\ \text{词汇表中所有词的点积得分的指数和} \end{aligned}
由于我们已经计算了对(food,tasty)的点积得分为0.64,现在让我们使用Softmax函数将其转换为概率。
≈
1.8965
28.1274
0.0674
6.74
%
\begin{aligned} P(tasty \mid food) &= \frac{e^{0.64}} {\displaystyle\sum_{w \in V} e^{v_{food}\cdot u_w}}\\[10pt] &\approx \frac{1.8965}{28.1274}\\[8pt] &\approx 0.0674\\[6pt] &\approx 6.74\% \end{aligned}
6.74%
在目标词为food的情况下,我们得到了tasty的约6.74%的概率。
这个概率是基于我们随机初始化的向量。
模型尚未从数据集中学习到有意义的关系。
但这里有一个对我们很重要的要点需要理解。
Softmax在计算候选词的概率时会考虑词汇表中的所有词。
即使tasty的点积保持不变,如果其他候选词的得分发生变化,它的概率也可能变化。
这是因为分母包含了所有19个词的得分。
通过这种方式,Softmax将点积得分转换为词汇表上的概率分布。
对于我们的目标-上下文示例(food,tasty),我们希望模型为tasty分配更高的概率,因为它确实是实际的上下文词。
随着模型从更多训练示例中学习,它会调整其向量以改进预测。
但模型如何学习调整这些向量呢?
我们将在下一部分探讨这个问题。
希望这篇博客能帮助你入门词嵌入。
现在,我们已经到达了一个可以开始探索嵌入是如何实际学习的阶段。
还有很多需要学习的内容,但我们将逐步探索,以建立对这一过程如何运作的深入理解。
第二部分再见!
如果你还没有阅读我最近关于 TF-IDF 的文章,可以在这里阅读:
如果有什么不清楚的地方,请随时在 LinkedIn 的评论中告诉我。
我非常期待听到你的反馈!
感谢阅读!