1.word2vec简介
word2vec,即词向量,就是一个词用一个向量来表示。是2013年Google提出的。word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuous bag of words,简称CBOW),以及两种高效训练的方法:负采样(negative sampling)和层序softmax(hierarchical softmax)。word2vec词向量可以较好地表达不同词之间的相似和类比关系。word2vec是一个NLP工具,它可以将所有的词向量化,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。
NLP(自然语言处理)里面,最细粒度的是词语,词语组成句子,句子再组成段落、篇章、文档。所以处理 NLP 的问题,首先要先处理词语。词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种。简单点来说就是把一个词语转换成对应向量的表达形式,来让机器读取数据。
2.语言模型
首先我们需要先思考这样一个问题:如何计算一段文本序列在某种语言下出现的概率?之所为称其为一个基本问题,是因为它在很多NLP任务中都扮演着重要的角色。例如,在机器翻译的问题中,如果我们知道了目标语言中每句话的概率,就可以从候选集合中挑选出最合理的句子做为翻译结果返回。
统计语言模型给出了这一类问题的一个基本解决框架。对于一段文本序列S=w1,w2,…,wT,它的概率可以表示为:
p(S)=p(w1,w2,w3,w4,w5,…,wt)
=p(w1)p(w2|w1)p(w3|w1,w2)…p(wt|w1,w2,…,wt-1)
即将序列的联合概率转化为一系列条件概率的乘积。问题变成了如何去预测这些给定previous words下的条件概率p(wt|w1,w2,…,wt−1)。常见的统计语言模型有N元文法模型(N-gram Model)
基于马尔科夫假设(Markov Assumption):下一个词的出现仅依赖于它前面的一个或几个词。
假设下一个词的出现依赖它前面的一个词,则有:
p(S)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|w1,w2,…,wn-1)=p(w1)p(w2|w1)p(w3|w2)…p(wn|wn-1) // bigram
假设下一个词的出现依赖它前面的两个词,则有:
p(S)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|w1,w2,…,wn-1)=p(w1)p(w2|w1)p(w3|w1,w2)…p(wn|wn-1,wn-2) // trigram
那么,我们在面临实际问题时,如何选择依赖词的个数,即n。
更大的n:对下一个词出现的约束信息更多,具有更大的辨别力;
更小的n:在训练语料库中出现的次数更多,具有更可靠的统计信息,具有更高的可靠性。
理论上,n越大越好,经验上,trigram用的最多,尽管如此,原则上,能用bigram解决,绝不使用trigram。
3. CBOW和skip-gram模型介绍
假设我们输入的一句话为 The quick brown fox jumps over the lazy dog.
设定我们的窗口大小为2(window_size=2),也就是说我们仅选输入词前后各两个词和输入词进行组合。
3.1 CBOW
CBOW模型如下图所示,该模型的特点是输入已知上下文,输出对当前单词的预测。
假设window_size取2时,利用CBOW模型可以得到:
([quick, brown],The)
([The, brown, fox],quick)
([The, quick, fox, jumps],brown)
([quick, brown, jumps, over],fox)
......
首先输入的是one-hot向量,第一层是一个全连接层,然后没有激活函数,输出层是一个softmax层,输出一个概率分布,表示词典中每个词出现的概率。
- 1 输入层:上下文单词的onehot. {假设单词向量空间dim为V,上下文单词个数为C},假定要预测的单词是fox,那么输入层为quick、brown、jumps、over,采用one-hot编码,分别为[0, 1, 0, 0, 0, 0, 0, 0, 0, 0]、[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]、[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]、[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
- 2 所有onehot分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W}
- 3 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1*N.
- 4 乘以输出权重矩阵W' {N*V}
- 5 得到向量 {1*V} 激活函数处理得到V-dim概率分布 {其中的每一维度代表着一个单词}
- 6 概率最大的index所指示的单词为预测出的中间词(target word)与true label的onehot做比较,误差越小越好(根据误差更新权重矩阵)
所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W'。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量,这个矩阵也叫做look up table,也就是说,任何一个单词的onehot乘以这个矩阵都将得到自己的词向量。
3.2 skip_gram
skip-gram只是逆转了CBOW的因果关系而已,即已知当前词语,预测上下文。
下图中,蓝色代表input word,方框内代表位于窗口内的单词。Training Samples(输入, 输出)
假设window_size取2时,利用CBOW模型可以得到:
(The, [quick, brown])
(quick, [The, brown, fox])
(brown, [The, quick, fox, jumps])
(fox, [quick, brown, jumps, over])
......
4. 高效训练方法
在CBOW和skip-gram讲解完成后,我们会发现Word2Vec模型是一个超级大的神经网络(权重矩阵规模非常大)。
举个例子,我们拥有10000个单词的词汇表,我们如果想嵌入300维的词向量,那么我们的输入-隐层权重矩阵和隐层-输出层的权重矩阵都会有 10000 x 300 = 300万个权重,在如此庞大的神经网络中进行梯度下降是相当慢的。更糟糕的是,你需要大量的训练数据来调整这些权重并且避免过拟合。百万数量级的权重矩阵和亿万数量级的训练样本意味着训练这个模型将会是个灾难。
下面主要介绍两种方法优化训练过程。
1.负采样(negative sampling)
负采样解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。
2.层序softmax也是解决这个问题的一种方法。
具体细节下次分享~