让电脑读懂你的语言——如何理解 Word2Vec
将单词向量化在 NLP 领域,是非常常见的一个技术。这篇文章介绍一下 Word2Vec 这个算法的具体思想。如果有什么理解不到位的地方也欢迎各位指正。
窗口、中心词与上下文
首先先介绍 窗口 的概念,窗口是指:当前的单词前后几个单词(包括当前词)。当然前后可发现距离都是可以自定义的;且有时候并不一定需要前后距离相同。在上述 窗口 这个概念介绍中,自然而然地引出了 中心词 与 上下文 这两个概念,他们分别是:
- 中心词:当前发现的单词;
- 上下文:这个单词 窗口 内(不含该单词的)所有单词。
以下面所示这句话作为例子:
当我们读取到这句话的时候,若我们选定 jumped 作为当前的中心词;则此时 [The, cat, over, the] 就是定义窗口范围为 [ − 2 , 2 ] [-2, 2] [−2,2] 情况下,这个单词的上下文。
单词向量
我们已经定义了中心词与上下文两个概念,这为单词向量化(实际上就是坐标化)打下了基础。之前介绍了 中心词 与 上下文 两个概。只要是一句话中的单词,他都具有作为上下文与中心词两种可能性。正如上述的例子中,你可以选择 jumped 作为中心词,那此时 over 就是其上下文;当你选择over 作为中心词,那此时 jumped 就属于其上下文。因此针对每个单词都可能出现的这两种情况,对一个单词姑且分别定义两个向量:中心词向量 v v v 、上下文向量 u u u 。
需要肯定的是,越高维度的向量就能表示越高维度的信息。比如:在二维下的一个点的坐标包含的信息肯定比在一维下的点所包含的信息要多。但对现实情况而言,电脑内存是有限的,同时还需要保证一定的算法执行效率,因此并不是越高的维度对单词的表示越好,大体上可以根据词汇量,进行降维的操作。
比如此时,假设我们词汇表中有 jumped 这个单词,我们可以假设单词的维度是
2
2
2 维的,则我们可以通过两个列向量来表示 jumped 这个单词:
v
jumped
=
[
×
×
]
,
u
jumped
=
[
×
×
]
v_{\text{jumped}}=\left[\begin{matrix}\times\\\times\end{matrix}\right], u_{\text{jumped}}=\left[\begin{matrix}\times\\\times\end{matrix}\right]
vjumped=[××],ujumped=[××]
Note: 很多地方都喜欢用一个大矩阵:
V
,
U
V,U
V,U 来表示所有单词的这些信息,这样表示我觉得容易弄混,可以直接用哈希来存储、表示这些向量更直观一些。
基于 Word2Vec 思想的单词向量化算法实现
词汇表中的所有向量可以用随机数进行初始化(一般用服从标准正态分布的随机数来建立)对于上述说的,用两个二维向量来表示这个单词,则其初始化为:
v
jumped
(
0
)
=
[
0.1017832
−
0.1918282
]
,
u
jumped
(
0
)
=
[
0.1835233
−
0.8995452
]
v^{(0)}_{\text{jumped}}=\left[\begin{matrix}0.1017832\\-0.1918282\end{matrix}\right], u^{(0)}_{\text{jumped}}=\left[\begin{matrix}0.1835233\\-0.8995452\end{matrix}\right]
vjumped(0)=[0.1017832−0.1918282],ujumped(0)=[0.1835233−0.8995452]
在训练过程中,我们需要有一个函数作为我们优化的目标。这里使用交叉熵函数来定义,也先姑且称其为 对数似然函数 (因为我们的目标是最大化这个函数)。推导见本文附录部分
在扫描文本的过程中,我们碰到的 中心词 记为
c
c
c ,出现在其 上下文 的集合记为
O
O
O ,对每个属于上下文的单词
o
∈
O
o\in O
o∈O 都有:
J
o
(
U
,
V
)
=
log
(
σ
(
u
o
T
v
c
)
)
+
1
∣
k
∣
∑
i
∈
k
log
(
σ
(
−
u
j
T
v
c
)
)
J_o(U,V)=\log \left(\sigma\left(u_o^Tv_c\right)\right)+\frac{1}{|k|}\sum_{i\in k}\log\left(\sigma\left(-u_j^Tv_c\right)\right)
Jo(U,V)=log(σ(uoTvc))+∣k∣1i∈k∑log(σ(−ujTvc))
其中
σ
(
x
)
\sigma(x)
σ(x) 是定义在
[
−
∞
,
∞
]
[-\infty,\infty]
[−∞,∞] 上的单调递增的函数,其值域在
(
0
,
1
)
(0,1)
(0,1) 上,用来刻画概率:
σ
(
x
)
=
1
1
+
exp
(
−
x
)
\sigma(x)=\frac{1}{1+\exp(-x)}
σ(x)=1+exp(−x)1
首先解释一下这里面的一些参数:
- U , V U,V U,V 其实是我们对所有单词构成的哈希表中的向量集合(包含中心词向量、上下文向量,具体参照上一个小节)。
- 这个函数第一项: log ( σ ( u o T v c ) ) \log \left(\sigma\left(u_o^Tv_c\right)\right) log(σ(uoTvc)) 代表了作为上下文的 o o o 与中心词 c c c 的距离。首先,这里的内积 u o T v c u_o^Tv_c uoTvc 就是上下文的 o o o 与中心词 c c c 的距离,将其结果转变成概率的形式,则有 σ ( u o T v c ) \sigma\left(u_o^Tv_c\right) σ(uoTvc) 。至于为什么要加上一个 log \log log ,这里实际上是由于这是一个对数似然函数(可以参考最大似然估计的主要思想,这里为了求最大值方便)。总的来说,两者内积越大,对应 log ( σ ( u o T v c ) ) \log \left(\sigma\left(u_o^Tv_c\right)\right) log(σ(uoTvc)) 越大。
- 函数第二项: 1 ∣ k ∣ ∑ i ∈ k log ( σ ( − u j T v c ) ) \frac{1}{|k|}\sum_{i\in k}\log\left(\sigma\left(-u_j^Tv_c\right)\right) ∣k∣1∑i∈klog(σ(−ujTvc)) 这里的 k k k 表示 所有 非存在于上下文中的单词的集合,而 ∣ k ∣ |k| ∣k∣ 则是表示集合 k k k 的大小。这一项与前面所描述的类似:两者内积越大,对应 log ( σ ( − u o T v c ) ) \log \left(\sigma\left(-u_o^Tv_c\right)\right) log(σ(−uoTvc)) 越小 。 但在实际操作中,词汇量较大的情况下,操作起来时间复杂度极高,因此可以采用随机采样的方式进行计算。
Remark: 关于这个 对数似然函数, 个人的理解是:第一项 表示最大化他们的协出现概率;第二项 表示最小化不相关词的协出现概率。
因此我们需要最大化这个 对数似然函数 ,就能够得到对所有单词向量的一个估计。
U
^
,
V
^
=
arg
max
U
,
V
∑
o
∈
O
J
o
(
U
,
V
)
=
arg
max
U
,
V
∑
o
∈
O
[
log
(
σ
(
u
o
T
v
c
)
)
+
1
∣
k
∣
∑
i
∈
k
log
(
σ
(
−
u
j
T
v
c
)
)
]
\begin{aligned} \hat U,\hat V &= \arg\max_{U,V}\sum_{o\in O}J_o(U,V)\\ &=\arg \max_{U,V}\sum_{o\in O}\left[\log \left(\sigma\left(u_o^Tv_c\right)\right)+\frac{1}{|k|}\sum_{i\in k}\log\left(\sigma\left(-u_j^Tv_c\right)\right)\right] \end{aligned}
U^,V^=argU,Vmaxo∈O∑Jo(U,V)=argU,Vmaxo∈O∑[log(σ(uoTvc))+∣k∣1i∈k∑log(σ(−ujTvc))]
这里可以才用梯度下降的方法求取(看作最小化其相反数)。具体梯度的推导见 CS224N Assignment 2: word2vec (43 Points) 这篇博客。
值得注意的是,每次扫描到一个中心词 c c c ,及其上下文 O O O,实际上,我们只更新了这个窗口内、以及采样得到的若干个不想管单词的向量。对于整篇文章来说,扫描整篇文章并不一定需要顺序采集每个单词作为中心词(实际上可以跳跃着选取,也就是skip-gram方法的思想)。
Appendix:对数似然函数的推导
用 sigmoid 函数定义概率(其中
D
D
D 是 output,
c
c
c 是中心词,
O
O
O 是上下文):
P
(
D
=
1
∣
o
,
c
,
U
,
V
)
=
σ
(
v
c
T
u
o
)
=
1
1
+
e
(
−
v
c
T
u
o
)
P(D=1 | o, c, U,V)=\sigma\left(v_{c}^{T} u_{o}\right)=\frac{1}{1+e^{\left(-v_{c}^{T} u_{o}\right)}}
P(D=1∣o,c,U,V)=σ(vcTuo)=1+e(−vcTuo)1
因此目标函数有:
U
,
V
=
argmax
U
,
V
∏
(
o
,
c
)
∈
D
P
(
D
=
1
∣
o
,
c
,
U
,
V
)
∏
(
w
,
c
)
∉
D
P
(
D
=
0
∣
w
,
c
,
U
,
V
)
=
argmax
U
,
V
∏
(
o
,
c
)
∈
D
P
(
D
=
1
∣
o
,
c
,
U
,
V
)
∏
(
w
,
c
)
∉
D
(
1
−
P
(
D
=
1
∣
w
,
c
,
U
,
V
)
)
=
argmax
U
,
V
∑
(
o
,
c
)
∈
D
log
P
(
D
=
1
∣
o
,
c
,
U
,
V
)
+
∑
(
w
,
c
)
∉
D
log
(
1
−
P
(
D
=
1
∣
w
,
c
,
U
,
V
)
)
=
argmax
U
,
V
∑
(
o
,
c
)
∈
D
log
1
1
+
exp
(
−
u
o
T
v
c
)
+
∑
(
w
,
c
)
∉
D
log
(
1
−
1
1
+
exp
(
−
u
w
T
v
c
)
)
=
argmax
U
,
V
∑
(
o
,
c
)
∈
D
log
1
1
+
exp
(
−
u
o
T
v
c
)
+
∑
(
w
,
c
)
∉
D
log
(
1
1
+
exp
(
u
w
T
v
c
)
)
\begin{aligned} U,V &=\underset{U,V}{\operatorname{argmax}} \prod_{(o, c) \in D} P(D=1 | o, c, U,V) \prod_{(w, c) \notin D} P(D=0 | w, c, U,V) \\ &=\underset{U,V}{\operatorname{argmax}} \prod_{(o, c) \in D} P(D=1 | o, c, U,V) \prod_{(w, c) \notin D}(1-P(D=1 | w, c, U,V)) \\ &=\underset{U,V}{\operatorname{argmax}} \sum_{(o, c) \in D} \log P(D=1 | o, c, U,V)+\sum_{(w, c) \notin D} \log (1-P(D=1 | w, c, U,V)) \\ &=\underset{U,V}{\operatorname{argmax}} \sum_{(o, c) \in D} \log \frac{1}{1+\exp \left(-u_{o}^{T} v_{c}\right)}+\sum_{(w, c) \notin D} \log \left(1-\frac{1}{1+\exp \left(-u_{w}^{T} v_{c}\right)}\right) \\ &=\underset{U,V}{\operatorname{argmax}} \sum_{(o, c) \in D} \log \frac{1}{1+\exp \left(-u_{o}^{T} v_{c}\right)}+\sum_{(w, c) \notin D} \log \left(\frac{1}{1+\exp \left(u_{w}^{T} v_{c}\right)}\right) \end{aligned}
U,V=U,Vargmax(o,c)∈D∏P(D=1∣o,c,U,V)(w,c)∈/D∏P(D=0∣w,c,U,V)=U,Vargmax(o,c)∈D∏P(D=1∣o,c,U,V)(w,c)∈/D∏(1−P(D=1∣w,c,U,V))=U,Vargmax(o,c)∈D∑logP(D=1∣o,c,U,V)+(w,c)∈/D∑log(1−P(D=1∣w,c,U,V))=U,Vargmax(o,c)∈D∑log1+exp(−uoTvc)1+(w,c)∈/D∑log(1−1+exp(−uwTvc)1)=U,Vargmax(o,c)∈D∑log1+exp(−uoTvc)1+(w,c)∈/D∑log(1+exp(uwTvc)1)
第一项对数下即为
σ
(
v
c
T
u
o
)
\sigma(v_c^Tu_o)
σ(vcTuo) ,第二项对数底下即为
σ
(
−
u
w
T
v
c
)
\sigma(-u_w^Tv_c)
σ(−uwTvc) 。因此推导出了上述似然函数的形式。
Appendix:其他形式的损失函数定义
softmax 回归本质上与逻辑回归类似(见多分类器:KNN,SVM,Softmax,2-Layer-Affine-Net(以图像分类为例子)),定义的 σ ( x ) \sigma(x) σ(x) 函数是一种将数值转换为概率的一种方法。
有贝叶斯条件概率下,该窗口中心词为
c
c
c 的概率可由下式表示(
c
c
c 是中心词,
O
O
O 是上下文的所有单词):
P
(
c
∣
O
)
=
exp
(
v
c
T
u
)
∑
o
∈
O
exp
(
v
o
T
u
)
P(c|O)=\frac{\exp(v_c^Tu)}{\sum_{o\in O}\exp(v_o^Tu)}
P(c∣O)=∑o∈Oexp(voTu)exp(vcTu)
我们需要最大化这个概率(这个概率即作为似然函数),由于取对数不改变其单调性:
U
^
,
V
^
=
arg
max
U
,
V
log
(
∏
o
∈
O
exp
(
v
c
T
u
)
∑
w
∉
O
exp
(
v
c
T
u
)
)
=
arg
max
U
,
V
∑
o
∈
O
[
v
c
T
u
o
−
log
(
∑
o
∈
O
exp
(
v
c
T
u
o
)
)
]
\begin{aligned} \hat U,\hat V &= \arg\max_{U,V}\log\left(\prod_{o\in O}\frac{\exp(v_c^Tu)}{\sum_{w\notin O}\exp(v_c^Tu)}\right)\\ &=\arg\max_{U,V}\sum_{o\in O}\left[v_c^Tu_o-\log\left(\sum_{o\in O}\exp(v_c^Tu_o)\right)\right] \end{aligned}
U^,V^=argU,Vmaxlog(o∈O∏∑w∈/Oexp(vcTu)exp(vcTu))=argU,Vmaxo∈O∑[vcTuo−log(o∈O∑exp(vcTuo))]
参考文献: