词嵌入(word2vec)
自然语言是一套用来表达含义的复杂系统。在这套系统中,词是表义的基本单元。顾名思义,词向量是用来表示词的向量,也可被认为是词的特征向量或表征。把词映射为实数域向量的技术也叫词嵌入(word embedding)。近年来,词嵌入已逐渐成为自然语言处理的基础知识
介绍
word2vec是Google于2013年推出的开源的获取词向量word2vec的工具包。它包括了一组用于word embedding的模型,这些模型通常都是用浅层(两层)神经网络训练词向量。
Word2vec的模型以大规模语料库作为输入,然后生成一个向量空间(通常为几百维)。词典中的每个词都对应了向量空间中的一个独一的向量,而且语料库中拥有共同上下文的词映射到向量空间中的距离会更近。
为何不采用one-hot向量
虽然one-hot词向量构造起来很容易,但通常并不是一个好选择。一个主要的原因是,one-hot词向量无法准确表达不同词之间的相似度,如我们常常使用的余弦相似度。
x
,
y
∈
R
d
\boldsymbol{x}, \boldsymbol{y} \in \mathbb{R}^d
x , y ∈ R d ,它们的余弦相似度是它们之间夹角的余弦值
x
⊤
y
∣
x
∣
∣
y
∣
∈
[
−
1
,
1
]
.
\frac{\boldsymbol{x}^\top \boldsymbol{y}}{|\boldsymbol{x}| |\boldsymbol{y}|} \in [-1, 1].
∣ x ∣ ∣ y ∣ x ⊤ y ∈ [ − 1 , 1 ] . 由于任何两个不同词的one-hot向量的余弦相似度都为0,多个不同词之间的相似度难以通过one-hot向量准确地体现出来。 例如: 1.“我爱学习”表示为[1,2,3] 2.“我爱篮球”表示为[1,3,3] 则它们的余弦相似度是它们之间夹角的余弦值:
x
⊤
y
∣
x
∣
∣
y
∣
=
1
∗
1
+
2
∗
3
+
3
∗
3
1
2
+
2
2
+
3
2
1
2
+
3
2
+
3
2
=
16
266
\frac{\boldsymbol{x}^\top \boldsymbol{y}}{|\boldsymbol{x}| |\boldsymbol{y}|} =\frac{1*1+2*3+3*3}{\sqrt{1^2+2^2+3^2}\sqrt{1^2+3^2+3^2}}=\frac{16}{\sqrt{266}}
∣ x ∣ ∣ y ∣ x ⊤ y = 1 2 + 2 2 + 3 2
1 2 + 3 2 + 3 2
1 ∗ 1 + 2 ∗ 3 + 3 ∗ 3 = 2 6 6
1 6 而使用one-hot编码时,任何两个不同词的one-hot向量的余弦相似度都为0
word2vec工具的提出正是为了解决上面这个问题 。 它将每个词表示成一个定长的向量,并使得这些向量能较好地表达不同词之间的相似和类比关系。word2vec工具包含了两个模型,即跳字模型(skip-gram) 和连续词袋模型(continuous bag of words,CBOW) 。接下来让我们分别介绍这两个模型以及它们的训练方法。
跳字模型
跳字模型假设基于某个词来生成它在文本序列周围的词 假设文本序列是“the”“man”“loves”“his”“son”。以“loves”作为中心词,设背景窗口大小为2。 跳字模型所关心的是,给定中心词“loves”,生成与它距离不超过2个词的背景词“the”“man”“his”“son”的条件概率,即
P
(
the"
,
man"
,
his"
,
son"
∣
“loves"
)
.
P(\textrm{the"},\textrm{man"},\textrm{his"},\textrm{son"}\mid\textrm{``loves"}).
P ( the" , man" , his" , son" ∣ “loves" ) . 假设给定中心词的情况下,背景词的生成是相互独立的,那么上式可以改写成
P
(
the"
∣
loves"
)
⋅
P
(
man"
∣
loves"
)
⋅
P
(
his"
∣
loves"
)
⋅
P
(
son"
∣
loves"
)
.
P(\textrm{the"}\mid\textrm{loves"})\cdot P(\textrm{man"}\mid\textrm{loves"})\cdot P(\textrm{his"}\mid\textrm{loves"})\cdot P(\textrm{son"}\mid\textrm{loves"}).
P ( the" ∣ loves" ) ⋅ P ( man" ∣ loves" ) ⋅ P ( his" ∣ loves" ) ⋅ P ( son" ∣ loves" ) . 在跳字模型中,每个词被表示成两个
d
d
d 维向量,用来计算条件概率。假设这个词在词典中索引为
i
i
i ,当它为中心词时向量表示为
v
i
∈
R
d
\boldsymbol{v}_i\in\mathbb{R}^d
v i ∈ R d ,而为背景词时向量表示为
u
i
∈
R
d
\boldsymbol{u}_i\in\mathbb{R}^d
u i ∈ R d 。设中心词
w
c
w_c
w c 在词典中索引为
c
c
c ,背景词
w
o
w_o
w o 在词典中索引为
o
o
o ,给定中心词生成背景词的条件概率可以通过对向量内积做softmax运算而得到:
P
(
w
o
∣
w
c
)
=
exp
(
u
o
⊤
v
c
)
∑
i
∈
V
exp
(
u
i
⊤
v
c
)
,
P(w_o \mid w_c) = \frac{\text{exp}(\boldsymbol{u}_o^\top \boldsymbol{v}c)}{ \sum{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)},
P ( w o ∣ w c ) = ∑ i ∈ V exp ( u i ⊤ v c ) exp ( u o ⊤ v c ) ,
其中词典索引集
V
=
0
,
1
,
…
,
∣
V
∣
−
1
\mathcal{V} = {0, 1, \ldots, |\mathcal{V}|-1}
V = 0 , 1 , … , ∣ V ∣ − 1 。假设给定一个长度为
T
T
T 的文本序列,设时间步
t
t
t 的词为
w
(
t
)
w^{(t)}
w ( t ) 。假设给定中心词的情况下背景词的生成相互独立,当背景窗口大小为
m
m
m 时,跳字模型的似然函数即给定任一中心词生成所有背景词的概率
∏
t
=
1
T
∏
−
m
≤
j
≤
m
,
j
≠
0
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
,
\prod_{t=1}^{T} \prod_{-m \leq j \leq m,\ j \neq 0} P(w^{(t+j)} \mid w^{(t)}),
t = 1 ∏ T − m ≤ j ≤ m , j = 0 ∏ P ( w ( t + j ) ∣ w ( t ) ) ,
这里小于1和大于
T
T
T 的时间步可以忽略。
训练跳字模型
跳字模型的参数是每个词所对应的中心词向量和背景词向量。训练中我们通过最大化似然函数来学习模型参数,即最大似然估计。这等价于最小化以下损失函数:
−
∑
t
=
1
T
∑
−
m
≤
j
≤
m
,
j
≠
0
log
,
P
(
w
(
t
+
j
)
∣
w
(
t
)
)
.
- \sum_{t=1}^{T} \sum_{-m \leq j \leq m,\ j \neq 0} \text{log}, P(w^{(t+j)} \mid w^{(t)}).
− t = 1 ∑ T − m ≤ j ≤ m , j = 0 ∑ log , P ( w ( t + j ) ∣ w ( t ) ) .
如果使用随机梯度下降,那么在每一次迭代里我们随机采样一个较短的子序列来计算有关该子序列的损失,然后计算梯度来更新模型参数。梯度计算的关键是条件概率的对数有关中心词向量和背景词向量的梯度。根据定义,首先看到
log
P
(
w
o
∣
w
c
)
=
u
o
⊤
v
c
−
log
(
∑
i
∈
V
exp
(
u
i
⊤
v
c
)
)
\log P(w_o \mid w_c) = \boldsymbol{u}_o^\top \boldsymbol{v}c - \log\left(\sum{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)\right)
log P ( w o ∣ w c ) = u o ⊤ v c − log ( ∑ i ∈ V exp ( u i ⊤ v c ) )
通过微分,我们可以得到上式中
v
c
\boldsymbol{v}_c
v c 的梯度
∂
log
,
P
(
w
o
∣
w
c
)
∂
v
c
=
u
o
−
∑
j
∈
V
exp
(
u
j
⊤
v
c
)
u
j
∑
i
∈
V
exp
(
u
i
⊤
v
c
)
=
u
o
−
∑
j
∈
V
(
exp
(
u
j
⊤
v
c
)
∑
i
∈
V
exp
(
u
i
⊤
v
c
)
)
u
j
=
u
o
−
∑
j
∈
V
P
(
w
j
∣
w
c
)
u
j
.
\begin{aligned} \frac{\partial \text{log}, P(w_o \mid w_c)}{\partial \boldsymbol{v}_c} &= \boldsymbol{u}o - \frac{\sum{j \in \mathcal{V}} \exp(\boldsymbol{u}_j^\top \boldsymbol{v}_c)\boldsymbol{u}j}{\sum{i \in \mathcal{V}} \exp(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}\ &= \boldsymbol{u}o - \sum{j \in \mathcal{V}} \left(\frac{\text{exp}(\boldsymbol{u}_j^\top \boldsymbol{v}c)}{ \sum{i \in \mathcal{V}} \text{exp}(\boldsymbol{u}_i^\top \boldsymbol{v}_c)}\right) \boldsymbol{u}_j\ &= \boldsymbol{u}o - \sum{j \in \mathcal{V}} P(w_j \mid w_c) \boldsymbol{u}_j. \end{aligned}
∂ v c ∂ log , P ( w o ∣ w c ) = u o − ∑ i ∈ V exp ( u i ⊤ v c ) ∑ j ∈ V exp ( u j ⊤ v c ) u j = u o − ∑ j ∈ V ( ∑ i ∈ V exp ( u i ⊤ v c ) exp ( u j ⊤ v c ) ) u j = u o − ∑ j ∈ V P ( w j ∣ w c ) u j .
它的计算需要词典中所有词以
w
c
w_c
w c 为中心词的条件概率。有关其他词向量的梯度同理可得。
训练结束后,对于词典中的任一索引为
i
i
i 的词,我们均得到该词作为中心词和背景词的两组词向量
v
i
\boldsymbol{v}_i
v i 和
u
i
\boldsymbol{u}_i
u i 。在自然语言处理应用中,一般使用跳字模型的中心词向量作为词的表征向量。
连续词袋模型
连续词袋模型与跳字模型类似。与跳字模型最大的不同在于,连续词袋模型假设基于某中心词在文本序列前后的背景词来生成该中心词。在同样的文本序列“the”“man”“loves”“his”“son”里,以“loves”作为中心词,且背景窗口大小为2时,连续词袋模型关心的是,给定背景词“the”“man”“his”“son”生成中心词“loves”的条件概率,也就是
P
(
loves"
∣
the"
,
man"
,
his"
,
“son"
)
.
P(\textrm{loves"}\mid\textrm{the"},\textrm{man"},\textrm{his"},\textrm{``son"}).
P ( loves" ∣ the" , man" , his" , “son" ) . 因为连续词袋模型的背景词有多个,我们将这些背景词向量取平均,然后使用和跳字模型一样的方法来计算条件概率。设
v
i
∈
R
d
\boldsymbol{v_i}\in\mathbb{R}^d
v i ∈ R d 和
u
i
∈
R
d
\boldsymbol{u_i}\in\mathbb{R}^d
u i ∈ R d 分别表示词典中索引为
i
i
i 的词作为背景词和中心词的向量(注意符号的含义与跳字模型中的相反)。设中心词
w
c
w_c
w c 在词典中索引为
c
c
c ,背景词
w
o
1
,
…
,
w
o
2
m
w_{o_1}, \ldots, w_{o_{2m}}
w o 1 , … , w o 2 m 在词典中索引为
o
1
,
…
,
o
2
m
o_1, \ldots, o_{2m}
o 1 , … , o 2 m ,那么给定背景词生成中心词的条件概率
P
(
w
c
∣
w
o
1
,
…
,
w
o
2
m
)
=
exp
(
1
2
m
u
c
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
∑
i
∈
V
exp
(
1
2
m
u
i
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
.
P(w_c \mid w_{o_1}, \ldots, w_{o_{2m}}) = \frac{\text{exp}\left(\frac{1}{2m}\boldsymbol{u}c^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}{ \sum_{i \in \mathcal{V}} \text{exp}\left(\frac{1}{2m}\boldsymbol{u}i^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}.
P ( w c ∣ w w o 1 , … , w o 2 m 在词典中索引为
o
1
,
…
,
o
2
m
o_1, \ldots, o_{2m}
o 1 , … , o 2 m ,那么给定背景词生成中心词的条件概率
P
(
w
c
∣
w
o
1
,
…
,
w
o
2
m
)
=
exp
(
1
2
m
u
c
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
∑
i
∈
V
exp
(
1
2
m
u
i
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
.
P(w_c \mid w_{o_1}, \ldots, w_{o_{2m}}) = \frac{\text{exp}\left(\frac{1}{2m}\boldsymbol{u}c^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}{ \sum_{i \in \mathcal{V}} \text{exp}\left(\frac{1}{2m}\boldsymbol{u}i^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}.
P ( w c ∣ w o 1 , … , w o 2 m ) = ∑ i ∈ V exp ( 2 m 1 u i < style="height: 2.7em;">o 2 m 在词典中索引为
o
1
,
…
,
o
2
m
o_1, \ldots, o_{2m}
o 1 , … , o 2 m ,那么给定背景词生成中心词的条件概率
P
(
w
c
∣
w
o
1
,
…
,
w
o
2
m
)
=
exp
(
1
2
m
u
c
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
∑
i
∈
V
exp
(
1
2
m
u
i
⊤
(
v
o
1
+
…
+
v
o
2
m
)
)
.
P(w_c \mid w_{o_1}, \ldots, w_{o_{2m}}) = \frac{\text{exp}\left(\frac{1}{2m}\boldsymbol{u}c^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}{ \sum_{i \in \mathcal{V}} \text{exp}\left(\frac{1}{2m}\boldsymbol{u}i^\top (\boldsymbol{v}{o_1} + \ldots + \boldsymbol{v}{o{2m}}) \right)}.
P ( w c ∣ w o 1 , … , w o 2 m ) = ∑ i ∈ V exp ( 2 m 1 u i ⊤ ( v o
P ( w c ∣ w