背景
最近在用fasttext进行文本分类,说到文本分类就不得不提起word2vec。Word2Vec是由Google的Mikolov等人提出的一个词向量计算模型,其重要意义在于将自然语言转换成了计算机能够理解的向量,能够更好地计算词与词之间的相似性。
One-Hot representation
一般比较常见的表示词向量的方式就是独热码表示(One-Hot representation),它首先将文章中不同的单词提取出来作为一个词集,然后把词集的大小作为词向量的维度,对于每个具体的词将对应的位置置1。例如,我们又下面5个词汇组成的词集[King,Queue,MAN,WOMAN,CHILD],则词Queue的One-Hot representation表达形式为[0,1,0,0,0],同理WOMAN的表达形式为[0,0,0,1,0]。
One-Hot representation用来表示词向量简单粗暴,但是有很多问题:
- 向量维度和词集大小一致,能够达到百万级,不利于内存计算
- 两个不一样的词做内积永远为0,无法表达词之间的相似关系
Distributed representation
Distributed representation被翻译为稠密表示(对于One-Hot representation只有在词汇对应位置上才置1,所以它是稀疏的,而Distributed representation不需要那么多维度来表示所有词汇,它可能在每个维度上都有值,所以在表现形式上更稠密),它通过训练的方式把每个词映射到一个较短的词向量上来,所有的词向量构成了向量空间,进而可以通过统计学方法来研究词与词之间的关系。
原理
word2vec接收分词后的文本作为输入,通过神经网络学习输入的每个词汇前后N个单词可能出现的词(这里应该是预测前面所有和后面所有的单词,但是简化为N-gram模型,相关原理详见文章最后的参考链接),最后产生一个稠密向量表示每个词。因为网络能够学习到一个词前后可能会出现什么词,所以通过word2vec产生的词向量可以计算词之间的相似性。
网络结构
word2vec是一个简单的三层神经网络,即一个输入层、一个隐藏层、一个输出层。输入层就是词的One-Hot representation,隐层的神经网络单元数量就是embedding size,即最终词向量的维度,隐藏层之后不需要使用激活函数,直接接到输出层。输出层是softmax(这里实际是Hierarchical Softmax,为了简化直接使用softmax),得到每个预测结果的概率。其网络结构示意图如下所示。
假设词集大小为10000,词向量的维度为300,即embedding_size=300
输入层
一个词的one-hot表达形式,长度为10000,例如[0,0,1,0…,0,0]
隐藏层
隐藏层的神经元数量就是词向量的长度,隐层参数是一个[10000,300]的矩阵。实际上,这个矩阵就是最后的词向量。其实输入和隐藏层的作用就是把词的one-hot表达形式转化为词向量的表达形式,下面的图更清楚一些
输出层
输出层就是一个10000维的向量,每个值代表一个词的概率。
skip-gram
skip-gram核心思想是通过中心词来预测周围词。假设中心词是cat,窗口长度为2,则根据cat预测左边两个词和右边两个词。例如,对于文本“the quick brown fox jumps over the lazy dog”,窗口长度为2时,有
- 当中心词为the时,有(the,quick),(the,brown)
- 当中心词为quick时,有(quick,the),(quick,brown),(quick,fox)
- 当中心词为brown时,有(brown,the),(brown,quick),(brown,fox),(brown,jumps)
- 当中心词为fox时,有(fox,quick),(fox,brown),(fox,jumps),(fox,over)
上面的窗口移动了4次,产生了13个样本。
CBOW
CBOW(continuous bag of words)的核心思想与skip-gram相反,它通过中心词周围的词来预测中心词。例如,对于文本“the quick brown fox jumps over the lazy dog”,窗口长度为2时,有
- 当中心词为the时,有([quick,brown],the)
- 当中心词为quick时,有([the,brown,fox],quick)
- 当中心词为brown时,有([the,quick,fox,jumps],brown)
- 当中心词为fox时,有([quick,brown,jumps,over],fox)
上面的窗口移动了4次,但是只产生了4个样本。这时候input是4个词,label是一个词,经过隐藏层之后输入的4个词被映射成了4个EmbedingSize维度的向量,对4个向量求平均后才能作为下一层的输入。
两个模型相比,skip-gram模型能产生更多的训练样本,抓住更多词与词之间语义上的细节,在语料多足够好的理想条件下,skip-gram模型优于CBOW模型。在语料较少的情况下,难以抓住足够词与词之间之间的细节,CBOW模型求平均的特性反而效果可能更好。
代码实现
tensorflow官网的示例中给出了word2vec的代码实现,但是该实现太繁琐,现给出简单版实现,详见word2vec。
网络结构
1 | # coding=utf-8 |
skip-gram数据准备
1 | class DataSet(object): |