本文章主要参考 吴恩达的深度学习课程和国立高等经济的选的自然语言处理课程。
Word2vec 概述
上一篇文章中,讲述了如何使用 one-hot 代表单个词,以及使用 BoW 模型代表一个句子。其中有一个很大问题就是,BoW模型无法表示语义。
比如,有如下两个句子:
- 猫躺在凳子上晒太阳
- 狗躺在凳子旁边晒太阳
如果使用 BoW 模型,此时因为 猫
和狗
是两个完全不同的词,所以会得到两个完全不同的 向量表示;也就是说没有理解句子的语义。那么如何解决这个问题呢?
这个时候就可以使用 Word2vec 模型了。该模型通过在大量语料库使用无监督学习的方式,可以“理解”到 猫
和狗
都是 动物
,然后 使用和上一节 one-hot -> BoW 相同或相似(取均值而不是求和)的方式就可以得到该句子有语义的向量表示。
模型的作用
该模型主要有两个通途:
- 表示相似的词:相似词可以得到相似的向量表示;
比如,猫和狗(动物);牡丹花、茉莉花、玫瑰花(都是花)等。
- 词的类比
举一个非常流行的例子如下:
男人(man)-> 妇女(woman)就像国王(KING)->?
此时该模型就可以求得 ?位置可能的词为 皇后(QUEEN)。
实际上,目前为止,该模型处理该问题还有很多的缺点。
怎么训练该模型呢?
本文主要讲述两种方式,即 CBOW 和 skip-gram
此外还有 GloVe 和 PPMI + SVD 等方法。
CBOW
以以下语料库为例:
- 我们笑着说再见,但我们都心知肚明,再见遥遥无期。
- 普普通通是一条铺平的道路:走起来很舒服,但却长不出鲜花。
如果使用上述句子进行CBOW模型训练的话,模型首先会使用 one-hot 方式表示所有的词;然后利用已有的语料库构造一个“监督”学习的模型。
即将 我们
输入模型训练的同时,将句子中后续的词 笑着
、再见
等词作为正例输入模型,并使用一个 softmax 层来输出结果。
即
我们
后面可能跟着笑着
、再见
等;
可以看到如果句子很长,模型可能会将 我们
和 遥遥无期
都考虑进来,所以这个时候CBOW模型又一个 窗口(window) 的变量来表示 只使用该词的前后 window 个词进行训练。
skip-gram
skip-gram 模型与 CBOW 模型的一个最大的区别在于 skip-gram 模型生成“监督”学习训练数据的时候,不是将这个window内的所有词都作为正样本,而是在这个window内随机采样不同的词作为正样本。
还是拿以上的语料库为例:
假如对 心知肚明
这个词进行 skip-gram 并且窗口大小等于3,此时随机生成三个正样本可能为:
心知肚明
->我们
心知肚明
->再见
心知肚明
->但
hierarchical softmax classifier
不管是 CBOW 模型还是 skip-gram 模型,因为都会采用 softmax 作为输出层,来预测该词后续词的概率,所以这个 softmax 的输出的值很大(等于整个语料库中 词汇量的大小),而使用 softmax 模型的运行速度会 很慢。
这个时候可以使用 hierarchical softmax classifier
分类器。
hierarchical softmax classifier
基本原理和二叉树相似,想仔细了解的同学请参考 becominghuman.ai/hierarchica…
负采样
如上所述,CBOW 模型 和 sip-gram 模型生成的监督学习问题都 只有正样本,没有负样本,可能会使得监督学习得到一个比较差的结果。负采样正是为了解决这个问题
怎么进行负采样呢?
只需要 从词汇表中随便拿出不在 window 范围内的词作为负样本。
还是使用上述例子:
心知肚明
->我们
-> 1(正样本)心知肚明
->荣荣
-> 0(负样本)心知肚明
->猫
-> 0(负样本)心知肚明
->人生
-> 0(负样本)
即使生成的负样本“不正确”也没有问题(概率极小不会造成太大影响)。
最后再讲生成的训练数据输入模型进行训练即可。
doc2vec
doc2vec 和 paragraph2vec 只是一个模型的两种不同的叫法。该模型主要用来评估 文档的相似度。
训练该模型的方式和 word2vec 相似但是不完全相同,本文就不多介绍了。
此处提出一个问题如下:
是否可以使用训练好的 word2vec 模型对句子中每一个词进行表示,最终求和得到最终的文档向量表示呢?
总结
本文主要讲解了 word2vec 模型的作用,和训练该模型的两种主要方式 CBOW 和 skip-gram。
然而在实际的开发过程中不一定需要自己来写一个模型,目前以及有很好的开源库实现了这个功能: