原创:李孟启
1.前言
⾃然语⾔是⼀套⽤来表达含义的复杂系统。在这套系统中,词是表义的基本单元。顾名思义,词向量是⽤来表示词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌⼊ (word embedding)。近年来,词嵌⼊已逐渐成为⾃然语⾔处理的基础知识。
2.为何不采⽤ONE-HOT向量
假设词典中不同词的数量(词典⼤⼩)为NNN,每个词可以和从000到N−1N-1N−1的连续整数⼀⼀对应。这些与词对应的整数叫作词的索引。 假设⼀个词的索引为 iii,为了得到该词的one-hot向量表示,我们创建⼀个全000的⻓为 NNN的向量,并将其第 iii位设成111。这样⼀来,每个词就表示成了⼀个⻓度为NNN的向量,可以直接被神经⽹络使⽤。
虽然one-hot词向量构造起来很容易,但通常并不是⼀个好选择。⼀个主要的原因是,one-hot词向量⽆法准确表达不同词之间的相似度,如我们常常使⽤的余弦相似度。对于向量 x,y∈Rd\boldsymbol{x}, \boldsymbol{y} \in \mathbb{R}^{d}x,y∈Rd,它们的余弦相似度是它们之间夹⻆的余弦值:
x⊤y∥x∥y∥∈[−1,1] \frac{x^{\top} y}{\|x\| y \|} \in[-1,1] ∥x∥y∥x⊤y∈[−1,1]
由于任何两个不同词的one-hot向量的余弦相似度都为0,多个不同词之间的相似度难以通过one-hot向量准确地体现出来。
word2vec⼯具的提出正是为了解决上⾯这个问题 。它将每个词表示成⼀个定⻓的向量,并使得这些向量能较好地表达不同词之间的相似和类⽐关系。word2vec⼯具包含了两个模型,即跳字模型(skip-gram)和连续词袋模型(continuous bag of words,CBOW)。接下来让我们分别介绍这两个模型以及它们的训练⽅法。
3.跳字模型
跳字模型假设基于某个词来⽣成它在⽂本序列周围的词。举个例⼦,假设⽂本序是“the”“man”“loves”“his”“son”。以“loves”作为中⼼词,设背景窗⼝⼤⼩为2。如图1所示,跳字模型所关⼼的是,给定中⼼词“loves”,⽣成与它距离不超过2个词的背景词“the”“man”“his”“son”的条件概率,即
P(" the", "man", "his", "son" ∣" loves" ). P(" \text{ the", "man", "his", "son" } \mid " \text { loves" }) \text {. } P(" the", "man", "his", "son" ∣" loves" ).
假设给定中⼼词的情况下,背景词的⽣成是相互独⽴的,那么上式可以改写成
P("the"∣"loves")⋅P("man"∣"loves")⋅P("his"∣"loves")⋅P(′son"∣"loves"). P("the" \mid " loves") \cdot P(" \operatorname{man} " \mid " loves") \cdot P(" his" \mid " loves") \cdot P('son" \mid " loves"). P("the"∣"loves")⋅P("man"∣"loves")⋅P("his"∣"loves")⋅P(′son"∣"loves").
图1 跳字模型关⼼给定中⼼词⽣成背景词的条件概率
在跳字模型中,每个词被表示成两个ddd维向量,⽤来计算条件概率。假设这个词在词典中索引为iii,当它为中⼼词时向量表示为vi∈Rdv_{i} \in \mathbb{R}^{d}vi∈Rd ,⽽为背景词时向量表示为 ui∈Rdu_{i} \in \mathbb{R}^{d}ui∈Rd。设中⼼词 wc\mathrm{w}_{\mathrm{c}}wc 在词典中索引为ccc,背景词ωo\omega_{o}ωo 在词典中索引为o ,给定中⼼词⽣成背景词的条件概率可以通过对向量内积做softmax运算⽽得到:
P(wo∣wc)=exp(uo⊤vc)∑i∈Vexp(ui⊤vc) P\left(w_{o} \mid w_{c}\right)=\frac{\exp \left(\boldsymbol{u}_{o}^{\top} \boldsymbol{v}_{c}\right)}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)} P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc)
其中词典索引集 V={
0,1,…,∣V∣−1}\mathcal{V}=\{0,1, \ldots,|\mathcal{V}|-1\}V={
0,1,…,∣V∣−1}。假设给定⼀个⻓度为 TTT的⽂本序列,设时间步ttt 的词为w(t)w^{(t)}w(t)。假设给定中⼼词的情况下背景词的⽣成相互独⽴,当背景窗⼝⼤⼩为 mmm时,跳字模型的似然函数即给定任⼀中⼼词⽣成所有背景词的概率
∏t=1T∏−m≤j≤m,j≠0P(w(t+j)∣w(t)) \prod_{t=1}^{T} \prod_{-m \leq j \leq m, j \neq 0} P\left(w^{(t+j)} \mid w^{(t)}\right) t=1∏T−m≤j≤m,j=0∏P(w(t+j)∣w(t))
这⾥⼩于111和⼤于TTT的时间步可以忽略。
4.训练跳字模型
跳字模型的参数是每个词所对应的中⼼词向量和背景词向量。训练中我们通过最⼤化似然函数来学习模型参数,即最⼤似然估计。这等价于最⼩化以下损失函数:
−∑t=1T∑−m≤j≤m,j≠0logP(w(t+j)∣w(t)) -\sum_{t=1}^{T} \sum_{-m \leq j \leq m, j \neq 0} \log P\left(w^{(t+j)} \mid w^{(t)}\right) −t=1∑T−m≤j≤m,j=0∑logP(w(t+j)∣w(t))
如果使⽤随机梯度下降,那么在每⼀次迭代⾥我们随机采样⼀个较短的⼦序列来计算有关该⼦序列的损失,然后计算梯度来更新模型参数。梯度计算的关键是条件概率的对数有关中⼼词向量和背景词向量的梯度。根据定义,⾸先看到
logP(wo∣wc)=uo⊤vc−log(∑i∈Vexp(ui⊤vc)) \log P\left(w_{o} \mid w_{c}\right)=\boldsymbol{u}_{o}^{\top} \boldsymbol{v}_{c}-\log \left(\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)\right) logP(wo∣wc)=uo⊤vc−log(i∈V∑exp(ui⊤vc))
通过微分,我们可以得到上式中 vc\boldsymbol{v}_{c}vc的梯度
∂logP(wo∣wc)∂vc=uo−∑j∈Vexp(uj⊤vc)uj∑i∈Vexp(ui⊤vc)=uo−∑j∈V(exp(uj⊤vc)∑i∈Vexp(ui⊤vc))uj=uo−∑j∈VP(wj∣wc)uj \begin{aligned} \frac{\partial \log P\left(w_{o} \mid w_{c}\right)}{\partial \boldsymbol{v}_{c}} &=\boldsymbol{u}_{o}-\frac{\sum_{j \in \mathcal{V}} \exp \left(\boldsymbol{u}_{j}^{\top} \boldsymbol{v}_{c}\right) \boldsymbol{u}_{j}}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)} \\ &=\boldsymbol{u}_{o}-\sum_{j \in \mathcal{V}}\left(\frac{\exp \left(\boldsymbol{u}_{j}^{\top} \boldsymbol{v}_{c}\right)}{\sum_{i \in \mathcal{V}} \exp \left(\boldsymbol{u}_{i}^{\top} \boldsymbol{v}_{c}\right)}\right) \boldsymbol{u}_{j} \\ &=\boldsymbol{u}_{o}-\sum_{j \in \mathcal{V}} P\left(w_{j} \mid w_{c}\right) \boldsymbol{u}_{j} \end{aligned} ∂vc∂logP(wo∣wc)=uo−∑i∈Vexp(u