Introduction
Word2Vec 是 Google 在 2013 年开源的一个词向量(Word Embedding)计算工具,其用来解决单词的分布编码问题,因其简单高效引起了工业界和学术界极大的关注。
我们先尝试着回答几个问题,以检测下自己对 Word2Vec 的理解。
- Word2Vec 两个算法模型的原理是什么,网络结构怎么画?
- 网络输入输出是什么?隐藏层的激活函数是什么?输出层的激活函数是什么?
- 目标函数/损失函数是什么?
- Word2Vec 如何获取词向量?
- Word2Vec 的两个模型哪个效果好哪个速度快?为什么?
- 推导一下参数如何更新?
- Word2Vec 加速训练的方法有哪些?
- 介绍下 Hierarchical Softmax 的计算过程,怎么把 Huffman 放到网络中的?参数是如何更新的?对词频低的和词频高的单词有什么影响?为什么?
- 介绍下 Negative Sampling,对词频低的和词频高的单词有什么影响?为什么?
- Word2Vec 有哪些参数,有没有什么调参的建议?
- Word2Vec 有哪些局限性?
注:由于本文公式比较多不适合 Wrod2Vec 入门,入门学习可以参考 McCormick 大佬的几篇系列教程:《Word2Vec Tutorial》。
Word Embedding
在聊 Word2Vec 之前,我们先来了解一下词向量,我们都知道字符变量在送到神经网络训练之前需要将其编码成数值变量,常见的编码方式有两种:
- One-Hot 编码:以字符变量的种类为向量长度,向量中仅一个元素为 1 其它均为 0,这种编码方式的缺点是数据稀疏,不适合作为神经网络的输入(参数更新慢,收敛速度慢,计算量大),且无法捕捉到词与词之间的关系(相互正交);
- 分布编码:将字符变量映射到固定长度的向量中,向量空间中的点可以表示某个字符变量,且字符间的距离有意义。理想状况下,两个对象越相似其在空间中的距离就越近。
举个简单的例子,使用 One-Hot 编码时 男=[1, 0],女=[0,1],而使用分布编码时,男=1, 女=0。我们可以看到分布编码占用的空间比 One-Hot 要小。
今天要聊的 Word2Vec 是一种典型的分布编码方式,通过训练浅层神经网络获得词向量。
Structure
Word2Vec 有两种网络结构:CBOW 和 Skip-Gram,其结构如下图所示:
CBOW 是用上下文预测当前单词,Skip-gram 是用当前词预测上下文,两种网络都可以概括为如下网络:
其中,网络的输入是 One-Hot 向量 w k = ( x 1 , x 2 . . . x k . . . x V ) w_k=(x_1,x_2...x_k...x_V) wk=(x1,x2...xk...xV),隐藏层无激活函数,输出层有 Softmax 函数,输出的是概率分布,预测目标也为 One-Hot 向量$w_j=(x_1,x_2…x_j…x_V) $。层与层之间采用全连接方式,并用反向传播训练网络。
输入层到隐藏层的映射矩阵为 W V × N W_{V \times N} WV×N,隐藏层到输出层的映射矩阵为 W N × V ′ W_{N \times V}^{'} WN×V′,也就是说对于任意的单词 $w_k $ 我们都可以有两种表示向量:
v w j = X k W T v w j ′ = X k W ′ v_{w_j} = X_k W^T \quad v_{w_j}^{'} = X_k W^{'} vwj=XkWTvwj′=XkW′
其中, X k X_k Xk 为单词 k 的 One-Hot 编码,大小为 (1, N)。这个操作的本质是把 W 的第 k 行复制给 v。举个例子:
为方便起见,我们将 v w j v_{w_j} vwj 成为输入向量, 将 v w j ′ v_{w_j}^{'} vwj′ 成为输出向量。
输出层 的计算方式采用 Softmax:
p ( w j ∣ w k ) = e x p ( v w j ′ T v w k ) ∑ i = 1 V e x p ( v w i ′ T v w k ) p(w_j|w_k) = \frac{exp({v_{w_j}^{'}}^Tv_{w_k})}{\sum_{i=1}^V exp({v_{w_i}^{'}}^Tv_{w_k})} p(wj∣wk)=∑i=1Vexp(vwi′Tvwk)exp(vwj′Tvwk)
我们目的是想让 y j y_j yj 的第 j 个位置的值越大越好,其他位置的值越小越好。
m a x p ( w j ∣ w k ) = m a x l o g ( p ( w j ∣ w k ) ) = v w j ′ T v w k − l o g ( ∑ i = 1 V e x p ( v w i ′ T v w k ) ) : = − E max \; p(w_j|w_k) = max \; log(p(w_j|w_k)) \\ ={v_{w_j}^{'}}^Tv_{w_k} - log(\sum_{i=1}^V exp({v_{w_i}^{'}}^Tv_{w_k})) := -E maxp(wj∣wk)=maxlog(p(wj∣wk))=vwj′Tvwk−log(i=1∑Vexp(vwi′Tvwk)):=−E
所以损失函数为: E = − l o g ( p ( w j ∣ w k ) ) E=-log(p(w_j|w_k)) E=−log(p(wj∣wk))。
我们利用反向传播来更新参数,首先输出向量求偏导:
∂ E ∂ w i , j ′ = ∂ E ∂ u j ′ ∂ u j ′ ∂ w i , j ′ = ( y j − p j ) ⋅ h i \frac{\partial E}{\partial w_{i,j}^{'}} = \frac{\partial E}{\partial u_{j}^{'}} \frac{\partial u_{j}^{'}}{\partial w_{i,j}^{'}} =(y_j-p_j) \cdot h_i \\ ∂wi,j′∂E=∂uj′∂E∂wi,j′∂uj′=(yj−pj)⋅hi
其中: u j ′ = v w j ′ T v w j u_{j}^{'} = {v_{w_j}^{'}}^Tv_{w_j} uj