白话 Word2Vec

这两天学习了下Word2Vector的理论和实现,原理什么的网上很多,就不搬运了,推荐看参考文献[1-3],这里主要讲下我对几个关键点的理解。

1、词向量的意义

为什么要生成词向量,或者说词向量解决原来哪个领域什么方法的哪些不足?我的理解是这玩意主要就是为了解决如何让计算机理解自然语言中单词含义的问题。当然,现在随着 word2vec 用法的推广,这里已经不仅仅是自然语言中单词的理解了,还可以是各种现实生活中计算机本来没有办法理解的概念,比如用户的观影行为、图片的主题等等,把这些计算机一脸蒙逼的东西转换为它们最喜欢的浮点向量,然后把理解这个计算机一脸蒙逼的行为转换成向量的运算,这样实际就是完成了人类世界各种概念向计算机世界的映射/翻译,为人工智能占领世界打下了坚实的基础(扯远了)。那词向量比之前的方法好在哪呢?给我印象最深的就是含义相近的词能用距离相近的向量来表示!至于其他的一些数学处理上的好处,感觉只是副产品。文献 [1-2] 提供了一种能专门训练词向量的方法,一份好的词向量是可以直接用于翻译等应用的,所以感觉当我们自己数据量不足的时候,可以考虑直接用别人训练出来的词向量。

2、训练过程

Mikolov 等人提出了两种模型(CBOW 和 Skip-gram)、两种目标函数(Hierarchical Softmax, HS 和 Negative Sampling, NS),所以乘一下就是4个训练过程,但是其实理解起来都是差不多的。

先整体讲一下它们的关系,CBOW 模型是根据一个词 $w$ 的上下文 $U$ 来预测 $w$,Skip-gram是 根据一个词 $w$ 来预测上下文 $U$。初看时我是一脸蒙逼的,预测啥?后来才发现,实际上这里讲预测有点歧义,就是一个训练网络参数的过程。下文的理解需要有点基础知识,比如Huffman 编码之类的。

基于 HS 的 CBOW 模型和 Skip-gram 模型

基于HS的CBOW模型实际上就是给定一个词 $w$ 的上下文 $U$ 中所有词的词向量 $v_u$ ($u \in U$),输出一个 Huffman 树,使得网络根据这些 $v_u$ 的和 $x_U$ 能顺着这个 Huffman 树一路找到词 $w$。这里的 Huffman 树是根据所有词的词频生成的,它的每个叶节点表示一个词 $i$,并记录该词的词向量 $v_i$,非叶节点针对每个单词 $w$ 都会生成一个参数向量 $\theta_w$)。那什么叫顺着 Huffman 树一路找到词 $w$呢?我们知道 Huffman 树是一棵二叉树,在任何一个非叶节点 $j$ 决定是往左走还是往右走的时候,实际上是用 $x_U^T\cdot \theta_w^j$ 来决定的,这类似于二分类问题,因此需要加一个激活函数(用的是 sigmoid 函数),但是这不重要,重要的是它要根据 $x_U^T\cdot \theta_w^j$ 来判断是往左走还是往右走。因此,整个 CBOW 模型实际上就是在计算如何给定 $x_U$ 来在 Huffman 树上一步一步找到 $w$ 所在的叶节点。这个框架定了,剩下就是把这个思路转换成优化方程,然后用 GD 的方法来迭代求解,求解的过程中会不断更新 $\theta_w$ 和 $v_u$。注意,CBOW 模型虽然说是根据 $w$ 的上下文 $U$ 来预测 $w$,但是它更新的是 $w$ 的上下文 $U$ 中词的词向量。

基于 HS 的 Skip-gram 模型也是一样的道理,但是它的输入是 $v_w$,目标是在 Huffman 树中找到 $w$ 的所有上下文 $u$ 所在的叶节点(把每次查找都乘起来就 OK 了)。然后又是一堆计算,得到一个迭代方程组,来更新 $\theta_u$ 和 $v_w$(跟上面的类似,$\theta_u^j$ 是用来控制根据 $v_w$ 决定在每个非叶节点 $j$ 是往左走还是往右走才能找到 $u$ 所在的叶节点)。

基于 HS 的目标函数有一个小问题,就是所有非叶节点 $i$ 会对所有的词 $w$ 训练参数向量 $\theta_w^i$,因此需要很大的数据量,而且存储量也很大。基于 NS 的目标函数就能大大减少参数的个数,下面详细讨论下。

基于 NS 的 CBOW 模型和 Skip-gram 模型

前面讲了,基于 HS 的模型生成的是 Huffman 树,每次训练是最大化找到某个词(根据上下文找一个词,或者根据词找它的上下文)的概率。而基于 NS 的模型则是最大化正确分类某个词的概率。前面提到了,在 Huffman 树上往下走的时候,相当于是一个二分类问题,那为什么不用更加直观的分类呢?

什么是更直观的分类呢?给定一个样本,比如说一个词 $w$ 及其上下文 $U$,这时候再从词库里随便挑一些小伙伴出来,目标就是区分 $w$ 和这些新伙伴谁是 $U$ 的那个他(CBOW 模型),或者区分 $U$ 和这些新伙伴,谁是 $w$ 的上下文(Skip-gram 模型)?当然,这些小伙伴也不是随机选的,用的是随机负采样(所以叫 Negtive Sampling),本质上就是一种带权采样,也就是出现次数越多的词采到的概率越大。

基于 NS 的 CBOW 模型输入还是一个词 $w$ 的上下文 $U$ 中所有词的词向量之和 $x_U$,以及随机选的小伙伴们 $F$,分类是对每个 $p\in {w} \cup F$,训练一个参数向量 $\theta_p$,然后根据 $x_U^T\cdot \theta_p$(借助 sigmoid 函数分类)来判断 $p$ 到底是不是 $w$?因此设置的目标函数就是最大化分对的概率同时最小化分错的概率,然后再用 GD 列出一堆迭代方程来求解。从这里可以看到,HS 是对 Huffman 树上到 $w$ 的每个非叶节点训练一个参数向量,而这里是对 $p\in {w} \cup F$ 训练参数向量,参数向量的个数少了很多($(N-1)\cdot N$ vs. $N$),但是训练时间却不一定。文献 [2] 给出的数据是 $\mid F\mid=5$ 时,NS 方法快,$\mid F\mid=15$ 时,HS 方法快。

基于 NS 的 Skip-gram 模型也是类似,就是给定 $w$ 的词向量及其上下文,再选一群小伙伴,最大化把 $w$ 的上下文正确分出来并且最小化分错的概率。

3、词向量的应用

参考文献

[1] Mikolov T, Chen K, Corrado G, et al. Efficient estimation of word representations in vector space[J]. arXiv preprint arXiv:1301.3781, 2013.
[2] Mikolov T, Sutskever I, Chen K, et al. Distributed representations of words and phrases and their compositionality[C]//Advances in neural information processing systems. 2013: 3111-3119.
[3] peghoty. word2vec 中的数学原理详解. http://www.cnblogs.com/peghoty/p/3857839.html.