1. Word2Vec 概述
Word2Vec 是 Google 在 2013 年推出的一个 NLP 工具,其核心特点是将单词转化为向量来表示。这样词与词之间就可以定量地度量它们之间的关系,挖掘词之间的联系。
用词向量来表示词并不是 Word2Vec 的首创。在很久之前就已经出现了。最早的词向量采用 One-Hot 编码(One-Hot Encoding),又称为一位有效编码。每个词向量的维度大小为整个词汇表的大小,对于词汇表中的每个具体词汇,将对应的位置置为 1。
例如,假设有 5 个词组成的词汇表:
- cat
- dog
- bird
- fish
- mouse
采用 One-Hot 编码方式来表示词向量非常简单,但缺点也是显而易见的:
- 词汇表很大:实际使用的词汇表经常是百万级以上,这么高维的数据处理起来会消耗大量的计算资源与时间。
- 无法体现相似关系:One-Hot 编码中所有词向量之间彼此正交,没有体现词与词之间的语义相似关系。
Distributed Representation(分布式表示)可以解决 One-Hot 编码存在的问题。它的思路是通过训练,将原来 One-Hot 编码的每个词都映射到一个较短的词向量上来。这个较短的词向量的维度可以由自己在训练时根据任务需要来指定。
下图是采用 Distributed Representation 的一个例子,将词汇表里的词用 "Royalty", "Masculinity", "Femininity" 和 "Age" 4 个维度来表示。King 这个词对应的词向量可能是 (0.99, 0.99, 0.05, 0.7)。当然在实际情况中,并不能对词向量的每个维度做一个很好的解释。
有了用 Distributed Representation 表示的较短的词向量,就可以较容易地分析词之间的关系了。比如将词的维度降维到 2 维,有一个有趣的研究表明,用下图的词向量表示词时,可以发现 King - Man + Woman ≈ Queen 这样的语义规律。
可见只要得到了词汇表里所有词对应的词向量,那么就可以做很多有趣的事情了。不过,怎么训练才能得到合适的词向量呢?针对这个问题,Google 的 Tomas Mikolov 在他的论文中提出了 CBOW 和 Skip-gram 两种神经网络模型。
2. Word2Vec 原理
Word2Vec 的训练模型本质上是只具有一个隐含层的神经元网络。
它的输入是采用 One-Hot 编码的词汇表向量,它的输出也是 One-Hot 编码的词汇表向量。
使用所有的样本,训练这个神经元网络,等到收敛之后,从输入层到隐含层的那些权重,便是每一个词的采用 Distributed Representation 的词向量。比如,上图中单词的 Word Embedding 后的向量便是矩阵 $W_{V\times N}$ 的第 i 行的转置。这样就把原本维数为 V 的词向量变成了维数为 N 的词向量(N 远小于 V),并且词向量间保留了一定的相关关系。
Google 的 Mikolov 在关于 Word2Vec 的论文中提出了 CBOW 和 Skip-gram 两种模型:
- CBOW:适合于数据集较小的情况。
- Skip-gram:在大型语料中表现更好。
其中 CBOW 使用围绕目标单词的其他单词(语境)作为输入,在映射层做加权处理后输出目标单词。 与 CBOW 根据语境预测目标单词不同,Skip-gram 根据当前单词预测语境。
假如有一个句子 "There is an apple on the table" 作为训练数据,CBOW 的输入为 (is, an, on, the),输出为 apple。而 Skip-gram 的输入为 apple,输出为 (is, an, on, the)。
3. CBOW 模型详解
- 输入层:上下文单词的 One-Hot 编码词向量,V 为词汇表单词个数,C 为上下文单词个数。以上文那句话为例,这里 C=4,所以模型的输入是 (is, an, on, the) 4 个单词的 One-Hot 编码词向量。
- 隐藏层计算:初始化一个权重矩阵 $W_{V\times N}$,然后用所有输入的 One-Hot 编码词向量左乘该矩阵,得到维数为 N 的向量 $\omega_1, \omega_2, ..., \omega_c$,这里的 N 根据任务需要设置。
- 聚合:将所得的向量相加求平均作为隐藏层向量 h。
- 输出层:初始化另一个权重矩阵 $W'_{N\times V}$,用隐藏层向量 h 左乘 $W'$,再经激活函数处理得到 V 维的向量 y,y 的每一个元素代表相对应的每个单词的概率分布。


