Word2Vec

  • 1. 背景知识
  • 2. CBOW, Skip-Gram介绍
  • 2.1 以单个词语为输入的情况
  • 2.2 CBOW
  • 2.3 Skip-Gram
  • 3. 优化计算效率的两种方法
  • 3.1 Hierarchical Softmax
  • 3.2 Negative Sampling


1. 背景知识

在NLP任务中,很多时候我们处理文本的细粒度的是词语,所以我们需要将词语转换成向量的形式以进行各式各样的计算。

最初也是最简单的一种词向量表达方式是 One-hot 编码词语,例如:

text: I love you
 Vocab: { I: 0, love: 1, you: 2}Wordvector: {I:[1,0,0], love: [0,1,0], you: [0,0,1]}

可以看到这种表达方式很直观,但是有缺陷:

  1. 词向量的维度 = vocab中词语数量。后者在实际中往往是几万甚至几十几百万,因此会有维度爆炸
  2. 只能单纯的表示词语在vocab的索引,无法表示词语之间的内在联系

有许多研究者就词向量的获取方式作了改进,我们今天讲的word2vec便是其中一种。wordvec是google团队在2013年发布的一个训练获取词向量的工具包,包含了两种训练训练词向量的模型(skip-gram, COBW)和训练优化工具(negative samping, hierarchy softmax)

2. CBOW, Skip-Gram介绍

2.1 以单个词语为输入的情况


word2vec 向量 示例 word2vec词向量维度_自然语言处理

从最简单的情况开始讲起,假设输入的文本只有一个单词。我们设 V = vocab size,N = hidden size。Input layer是一个 (V*1) 大小的embedding layer : {word2vec 向量 示例 word2vec词向量维度_神经网络_02}。word2vec 向量 示例 word2vec词向量维度_nlp_03为1代表该词语在输入文本中出现。以单个词语为输入时,意味着{word2vec 向量 示例 word2vec词向量维度_神经网络_02}只有一个1值。

word2vec 向量 示例 word2vec词向量维度_自然语言处理_05是input 和 hidden之间的权重矩阵,每一行代表一个与input word相关的N维向量,我们用word2vec 向量 示例 word2vec词向量维度_自然语言处理_06表示。对于单个词语的输入,假设word2vec 向量 示例 word2vec词向量维度_nlp_07,我们有:

word2vec 向量 示例 word2vec词向量维度_自然语言处理_08

注意到word2vec 向量 示例 word2vec词向量维度_nlp_07,所以h其实就是W的第k行,word2vec 向量 示例 word2vec词向量维度_自然语言处理_10便是输入词word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_11的向量表示。

通过hidden layer到output layer中的权重矩阵word2vec 向量 示例 word2vec词向量维度_自然语言处理_12,我们可以计算出词汇表中每个词语的得分:

word2vec 向量 示例 word2vec词向量维度_nlp_13

word2vec 向量 示例 word2vec词向量维度_nlp_14word2vec 向量 示例 word2vec词向量维度_神经网络_15的第j列,然后我们用softmax得到所有词语的后验概率:


word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_16

word2vec 向量 示例 word2vec词向量维度_词向量_17便是对应output layer的第j个词。

我们注意到,对于输入词word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_11,他在W和W’中有两种向量形式:word2vec 向量 示例 word2vec词向量维度_神经网络_19,接下来我们把分别称为词语word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_11输入向量(input vector)和输出向量(output vector)。

更新输出向量:

我们要最大化word2vec 向量 示例 word2vec词向量维度_神经网络_21

word2vec 向量 示例 word2vec词向量维度_自然语言处理_22


word2vec 向量 示例 word2vec词向量维度_自然语言处理_23便是我们的损失函数, word2vec 向量 示例 word2vec词向量维度_nlp_24是实际输出词语的index。然后反向传播更新输出向量

word2vec 向量 示例 word2vec词向量维度_词向量_25

从式子中可以看出,更新一次,我们要检查vocab中所有词的概率。

更新输入向量:


word2vec 向量 示例 word2vec词向量维度_神经网络_26

E对输入向量W求导,得到一个V*N的矩阵,因为只有一个输入词,所以该矩阵只有一行是非0的,值为word2vec 向量 示例 word2vec词向量维度_nlp_27,然后便可以对W进行更新:


word2vec 向量 示例 word2vec词向量维度_nlp_28

注意,只有word2vec 向量 示例 word2vec词向量维度_自然语言处理_10那一行得到了更新。

讲过多次训练,最终,输入词的词向量维word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_30

2.2 CBOW


word2vec 向量 示例 word2vec词向量维度_词向量_31

直观来看,CBOW实际上是以上下文的方式来预测输出的词,我们需要设置一个上下文词语数量skip_window来决定窗口值C, 比如

Text: I love you three thousands.

Window size: skip_window = 2,C=2*skip_window+1=5

假设我们的输入词是 {I, love, three, thousands}, 我们的预测就应该是{you}。参数与2.1中的参数设置基本相同,hidden layer的值为:


word2vec 向量 示例 word2vec词向量维度_神经网络_32

C为窗口值5,损失函数也随即成了:


word2vec 向量 示例 word2vec词向量维度_神经网络_33

输出输入向量更新为:


word2vec 向量 示例 word2vec词向量维度_词向量_34

word2vec 向量 示例 word2vec词向量维度_词向量_35

注意,对于所有的输入词,输入向量word2vec 向量 示例 word2vec词向量维度_自然语言处理_36都是同一个矩阵。

2.3 Skip-Gram


word2vec 向量 示例 word2vec词向量维度_神经网络_37

直观来看,skip-gram实际上利用单个词预测上下文。我们设置skip_window和num_skip两个参数,前者代表上文或者下文的个数,后者代表从窗口中选取输出词的数量。同样对于文本"I love you three thousand":

设 skip_window = 1, num_skip=3, 意味着我们的窗口值(包括输入词)为span = 2*1+1 = 5, 输出词个数为3,即:

Input: “you” output=[“I love you”, “love you three”, “you three thousand”)]

损失函数为:

word2vec 向量 示例 word2vec词向量维度_神经网络_38

其中

word2vec 向量 示例 word2vec词向量维度_词向量_39

为输出层所有词的错误和。

输出向量更新公式:


word2vec 向量 示例 word2vec词向量维度_神经网络_40

输入向量更新公式:

word2vec 向量 示例 word2vec词向量维度_nlp_41

word2vec 向量 示例 word2vec词向量维度_自然语言处理_42

3. 优化计算效率的两种方法

我们注意到,输入向量的学习是很轻松的,但是输出向量的更新却很繁重。对于每个训练示例(training instance),我们都需要遍历一遍vocab中的所有词语,计算每个词语的概率,损失,然后更新相对应输出向量,这对于动辄几万几十万的vocab来说计算成本巨大,所以有一个优化的思路是减少每次训练是需要更新的输出向量。

3.1 Hierarchical Softmax

Hierarchical Softmax是一个利用霍夫曼树来表示vocab中所有词来达到优化softmax计算的方法。首先,将原先模型的输出向量word2vec 向量 示例 word2vec词向量维度_自然语言处理_43矩阵替代成如下的霍夫曼树:


word2vec 向量 示例 word2vec词向量维度_词向量_44

白色的叶结点代表输出层的词,共V个; 黑色结点为内部节点,共V-1个。图中显示从隐藏层到输出层word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_45的路径word2vec 向量 示例 word2vec词向量维度_nlp_46,路径长度word2vec 向量 示例 word2vec词向量维度_自然语言处理_47word2vec 向量 示例 word2vec词向量维度_自然语言处理_48代表该路径上的第i个内部节点。

原先用输出向量表示输出词word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_45,现在变成了用word2vec 向量 示例 word2vec词向量维度_nlp_46路径上每个节点表示。树中每一个内部节点都有一个输出向量word2vec 向量 示例 word2vec词向量维度_自然语言处理_51,所以相应的,输出词的概率也变成了:


word2vec 向量 示例 word2vec词向量维度_神经网络_52

word2vec 向量 示例 word2vec词向量维度_nlp_53表示节点word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_54的左节点,

word2vec 向量 示例 word2vec词向量维度_nlp_55

直观的理解就是预测值word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_56为实际值word2vec 向量 示例 word2vec词向量维度_nlp_57的概率是在word2vec 向量 示例 word2vec词向量维度_nlp_46的每一个节点都取左节点的概率。

更新的式子为:

word2vec 向量 示例 word2vec词向量维度_自然语言处理_59

其中

word2vec 向量 示例 word2vec词向量维度_自然语言处理_60


就是路径上每个词语的内部节点的预测error。我们根据词频构建霍夫曼树,出现频率越高的词拥有越短的路径(内部节点越少),所需要更新的word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_61也越少。因此,我们的更新参数时的计算复杂度从原来的O(V)减少到了O(logV)。当然,我们的总参数量并没有显著减少(word2vec 向量 示例 word2vec词向量维度_nlp_62)。

3.2 Negative Sampling

Negative Sampling的优化思路简单暴力,我们称输出词为正样本,非输出词为负样本,我们基于经验选择特定的概率分布作为样本的噪音分布word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_63,基于word2vec 向量 示例 word2vec词向量维度_word2vec 向量 示例_63选择K个负样本:

word2vec 向量 示例 word2vec词向量维度_词向量_65


word2vec 向量 示例 word2vec词向量维度_神经网络_66

更新方程:


word2vec 向量 示例 word2vec词向量维度_自然语言处理_67

所以,每次更新,我们只需要更新正样本和K个负样本就好了,显著地减少了计算时间。

参考资料:
Rong, Xin. “word2vec parameter learning explained.” arXiv preprint arXiv:1411.2738 (2014).