【NLP学习笔记】word2vec

一、word2vec

简而言之,word2vec模型本质上是一个简化的神经网络。
主要由 CBOW(Continuous Bag-of-Words) 与Skip-Gram两种模型组成。如下图:

  • CBOW对小型数据库比较合适。
  • 而Skip-Gram在大型语料中表现更好。
    【NLP学习笔记】word2vec
CBOW模型 和 skip-gram模型

二、CBOW 和 skip-gram 最简单的情形

  • 我们先来看个最简单的情形。假设, y 是 x 的上下文,所以 y 只取上下文里一个词语的时候,语言模型就变成:

用当前词 x 预测它的下一个词 y

  • 接下来就可以看看 Skip-gram 的网络结构
    【NLP学习笔记】word2vec
  • 输入是One-Hot Vector,Hidden Layer的**函数是线性的,相当于没做任何处理(这也是 Word2vec 简化之前语言模型的独到之处)。Output Layer维度跟Input Layer的维度一样,用的是Softmax回归。
  • 我们要训练这个神经网络,用反向传播算法,本质上是链式求导。
  • 当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数(这里特指神经网络的权重),即隐层的权重矩阵。
  • 比如现在输入一个 x 的 one-hot encoder: [1,0,0,…,0],对应文本中某个词语,则在输入层到隐含层的权重里,只有对应 1 这个位置的权重被**,这些权重的个数,跟隐含层节点数是一致的,从而这些权重组成一个向量 Vx 来表示x,而因为每个词语的 one-hot encoder 里面 1 的位置是不同的,所以,这个向量 Vx 就可以用来唯一表示 x。
  • 注意:上面两段话说的就是 Word2vec 的精髓!!
  • 需要提到一点的是,这个词向量的维度(与隐含层节点数一致)一般情况下要远远小于词语总数 V 的大小,所以 Word2vec 本质上是一种降维操作——把词语从 one-hot encoder 形式的表示降维到 Word2vec 形式的表示。

三、Skip-gram 更一般的情形

上面讨论的是最简单情形,即 输出 y 只有一个词,当 y 有多个词时,网络结构如下:
【NLP学习笔记】word2vec

可以看成是 单个x->单个y 模型的并联,cost function 是单个 cost function 的累加**(取log之后)**
至于模型是如何并联、 cost function 的形式怎样,请仔细阅读参考资料 Xin Rong 的论文:『word2vec Parameter Learning Explained』

组成

四、CBOW更一般的情形

  • 基本思想:用一个词语作为输入,来预测它周围的上下文!

CBOW的训练模型,或者说 网络结构,如图所示
【NLP学习笔记】word2vec

  • 注意到,跟 Skip-gram 的模型并联不同,这里是输入变成了多个单词,所以要对输入处理下(一般是求和然后平均),输出的 cost function 不变,在此依然不展开,建议阅读参考资料Xin Rong 的论文:『word2vec Parameter Learning Explained』
  • 1 输入层:上下文单词的 one-hot 向量表示. {假设单词向量空间dim为V,即有V个词,上下文单词个数为C}
  • 2 所有 one-hot 向量分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W}
  • 3 所得的向量 {因为是one-hot所以为向量} 相加求平均作为隐层向量, size为1N.
  • 4 乘以输出权重矩阵W’ {N*V}
  • 5 得到向量 {1V} **函数处理得到V-dim概率分布 {PS: 因为是onehot,其中的每一维都代表着一个单词}----因为我们期望的是最终的结果更接近与one-hot形式,而one-hot在格式上只有一位为1,故每一维(每个格子)表示一个词。
  • 6 概率最大的index所指示的单词为预测出的中间词(target word)与true label的one-hot做比较,误差越小越好(根据误差更新权重矩阵)

所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W’。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table(其实聪明的你已经看出来了,其实这个look up table就是矩阵W自身),也就是说,任何一个单词的one-hot向量 乘以 这个矩阵 都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。

举例说明:
【NLP学习笔记】word2vec

  • 窗口大小是2,表示选取coffe前面两个单词和后面两个单词,作为input词。
    【NLP学习笔记】word2vec
  • 假设我们此时得到的概率分布已经达到了设定的迭代次数,那么现在我们训练出来的look up table应该为矩阵W。
  • 即,任何一个单词的one-hot表示乘以这个矩阵都将得到自己的word embedding。

五、Skip-Gram

  • 基本思想:用一个词语的上下文作为输入,来预测这个词语本身!

从直观上理解,Skip-Gram是给定input word来预测上下文。

**接下来我们来看看如何训练我们的神经网络。**假如我们有一个句子“The dog barked at the mailman”。

首先我们选句子中间的一个词作为我们的输入词,例如我们选取“dog”作为input word;

  • 有了input word以后,我们再定义一个叫做skip_window的参数,它代表着我们从当前input word的一侧(左边或右边)选取词的数量。如果我们设置skip_window=2,那么我们最终获得**窗口中的词(包括input word在内)**就是[‘The’, ‘dog’,‘barked’, ‘at’]。skip_window=2代表着选取左input word左侧2个词和右侧2个词进入我们的窗口,所以整个窗口大小span=2x2=4。
  • 另一个参数叫num_skips,它代表着我们从整个窗口中选取多少个不同的词作为我们的output word,当skip_window=2,num_skips=2时,我们将会得到三组 (input word, output word) 形式的训练数据,即 (‘dog’, ‘barked’),(‘dog’, ‘the’),(‘dog’, ‘at’)。
  • 简言之:当num_skips=2, windowsize=2时,当dog为目标词时,可选范围为[the, barked, at], 训练组合是随便从里面挑一个词 同 输入词dog组成label。

神经网络基于这些训练数据将会输出一个概率分布,这个概率代表着我们的词典中的每个词是output word的可能性。这句话有点绕,我们来看个栗子。第二步中我们在设置skip_window和num_skips=2的情况下获得了两组训练数据。假如我们先拿一组数据 (‘dog’, ‘barked’) 来训练神经网络,那么模型通过学习这个训练样本,会告诉我们词汇表中每个单词是“barked”的概率大小。

**模型的输出概率代表着到我们词典中每个词有多大可能性跟input word同时出现。**举个栗子,如果我们向神经网络模型中输入一个单词“中国“,那么最终模型的输出概率中,像“英国”, ”俄罗斯“这种相关词的概率将远高于像”苹果“,”蝈蝈“非相关词的概率。因为”英国“,”俄罗斯“在文本中更大可能在”中国“的窗口中出现。

  • 我们将通过给神经网络输入文本中成对的单词来训练它完成上面所说的概率计算。

下图给出了一些我们的训练样本的例子。我们选定句子“The quick brown fox jumps over lazy dog”,设定我们的窗口大小为2(window_size=2),也就是说我们 仅 选输入词前后各两个词 和 输入词 进行组合。下图中,蓝色代表input word,方框内代表位于窗口内的单词。Training Samples(输入, 输出)

【NLP学习笔记】word2vec
**我们的模型将会从每对单词出现的次数中学习到统计结果。**例如,我们的神经网络可能会得到更多类似(“中国“,”英国“)这样的训练样本对,而对于(”英国“,”蝈蝈“)这样的组合却看到的很少。因此,当我们的模型完成训练后,给定一个单词”中国“作为输入,输出的结果中”英国“或者”俄罗斯“要比”蝈蝈“被赋予更高的概率。

再次提醒,最终我们需要的是训练出来的权重矩阵。

六、怎么用训练出的 权重矩阵?

经过训练得出的权重矩阵,每一列就是一个词的embedding向量,用这些向量代替one-hot向量,进行下一步的训练。

七、word2vec之训练tricks

  • 实际上,Mikolov 那篇论文 『Efficient estimation of word representations in vector space』 里提到的 hierarchical softmax 和 negative sampling,并不是 Word2vec 的精髓,只是它的训练技巧,但也不是它独有的训练技巧。
  • Hierarchical softmax 只是 softmax 的一种近似形式(详见参考资料7.),而 negative sampling 也是从其他方法借鉴而来。
  • 为什么要用训练技巧呢? 因为,Word2vec 本质上是一个语言模型,它的输出节点数是 V 个,对应了 V 个词语,本质上是一个多分类问题,但实际当中,词语的个数非常非常多,会给计算造成很大困难,所以需要用技巧来加速训练。

[4] 总结了一下这两个 trick 的本质,有助于大家更好地理解,在此也不做过多展开,有兴趣的同学可以深入阅读参考资料 [5-10]

  • hierarchical softmax:本质是把 N 分类问题变成 log(N)次二分类

  • negative sampling:本质是预测总体类别的一个子集

八、实战

实际上在真正应用的时候,只需要调用 Gensim (一个 Python 第三方库)的接口就可以。但对理论的探究仍然有必要,如此方能更好地知道参数的意义、模型结果受哪些因素影响,以及举一反三地应用到其他问题当中,甚至更改源码以实现自己定制化的需求。

  • 解读 Gensim 里 Word2vec 模型的参数含义
  • 基于相应语料训练 Word2vec 模型,并评估结果
  • 对模型结果调优

参考

[1] word2vec 中的数学原理详解
[2] word2vec 中的数学原理详解(一)目录和前言
[3] 通俗理解word2vec
[4] [NLP] 秒懂词向量Word2vec的本质
[5] 北漂浪子的博客:『深度学习word2vec 笔记之基础篇』
[6] Yoav Goldberg 的论文:『word2vec Explained- Deriving Mikolov et al.’s Negative-Sampling Word-Embedding Method』
[7] Xin Rong 的论文:『word2vec Parameter Learning Explained』
[8] 来斯惟的博士论文『基于神经网络的词和文档语义向量表示方法研究』以及他的博客(网名:licstar)
[9] 几位大牛在知乎的回答:『word2vec 相比之前的 Word Embedding 方法好在什么地方?』
[10] Sebastian 的博客:『On word embeddings - Part 2: Approximating the Softmax』
[]
[]