Word2vec
在聊 Word2vec 之前,先聊聊 NLP (自然语言处理)。NLP 里面,最细粒度的是 词语,词语组成句子,句子再组成段落、篇章、文档。所以处理 NLP 的问题,首先就要拿词语开刀。
举个简单例子,判断一个词的词性,是动词还是名词。用机器学习的思路,我们有一系列样本(x,y),这里 x 是词语,y 是它们的词性,我们要构建 f(x)->y 的映射,但这里的数学模型 f(比如神经网络、SVM)只接受数值型输入,而 NLP 里的词语,是人类的抽象总结,是符号形式的(比如中文、英文、拉丁文等等),所以需要把他们转换成数值形式,或者说——嵌入到一个数学空间里,这种嵌入方式,就叫词嵌入(word embedding),而 Word2vec,就是词嵌入( word embedding) 的一种。
2013年,Google开源了一款用于词向量计算的工具——word2vec。word2vec可以在百万数量级的词典和上亿的数据集上进行高效地训练;其次,该工具得到的训练结果——词向量(word embedding),可以很好地度量词与词之间的相似性。随着深度学习(Deep Learning)在自然语言处理中应用的普及,很多人误以为word2vec是一种深度学习算法。其实word2vec算法的背后是一个浅层神经网络。另外需要强调的一点是,word2vec是一个计算word vector的开源工具。当我们在说word2vec算法或模型的时候,其实指的是其背后用于计算word vector的CBoW模型和Skip-gram模型。
NLP词的表示方法类型
1、词的独热表示one-hot
2、词的分布式表示 distributed representation
词的分布式表示主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示
基于神经网络的分布表示又称为词向量或者词嵌入。 2001年, Bengio 等人正式提出神经网络语言模型( Neural Network Language Model ,NNLM),该模型在学习语言模型的同时,也得到了词向量。所以请注意一点:词向量可以认为是神经网络训练语言模型的副产品。通过神经网络训练语言模型可以得到词向量,那么,究竟有哪些类型的神经网络语言模型呢?个人所知,大致有这么些:
a) Neural Network Language Model ,NNLM
b) Log-Bilinear Language Model, LBL
c) Recurrent Neural Network based Language Model,RNNLM
d) Collobert 和 Weston 在2008 年提出的 C&W 模型
e) Mikolov 等人提出了 CBOW( Continuous Bagof-Words)和 Skip-gram 模型
如今我们主要用到的是CBOW和Skip-gram模型。
要想得到一个词的向量表达方法,并且这个向量的维度很小,而且任意两个词之间是有联系的,可以表示出在语义层面上词语词之间的相关信息。我们就需要训练神经网络语言模型,即CBOW和Skip-gram模型。这个模型的输出我们不关心,我们关心的是模型中第一个隐含层中的参数权重,这个参数矩阵就是我们需要的词向量。它的每一行就是词典中对应词的词向量,行数就是词典的大小。
- 如果是用一个词语作为输入,来预测它周围的上下文,那这个模型叫做『Skip-gram 模型』
- 而如果是拿一个词语的上下文作为输入,来预测这个词语本身,则是 『CBOW 模型』
CBOW
CBOW(Continuous Bag-of-Word Model)又称连续词袋模型,是一个三层神经网络。如下图所示,该模型的特点是输入已知上下文,输出对当前单词的预测。

其学习目标是最大化对数似然函数:

其中,w表示语料库C中任意一个词。
下面上一个更细节的一个图:

[C,V]*[V,N]=[C,N]------->[1,N]
[1,N]*[N,V]=[1,V]
公式咱们就不放了,网络计算的步骤:
输入层:上下文单词的onehot。(假设单词向量空间dim为V,上下文单词个数为C)
所有onehot分别乘以共享的输入权重矩阵W(V*N矩阵,N为自己设定的数,初始化权重矩阵W)
所得的向量 (注意onehot向量乘以矩阵的结果) 相加求平均作为隐层向量, size为1*N.
乘以输出权重矩阵W’ {N*V}
得到向量 {1*V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
与true label的onehot做比较,误差越小越好。loss function(一般为交叉熵代价函数)
我们并不关心输出的内容,预测的结果不重要,重要的是训练完成后第一个全连接层的参数就是我们要的word embedding矩阵。

跳字模型(skip-gram)
通过中心词来推断上下文一定窗口内的单词。

[1,V]*[V,d]=[1,d] d为词向量的维度 [V,d]为所有词的热编码[V,V]在d维空间的映射W[V,d]
[1,d]*[d,V]=[1,V] 重复c次------>[C,V] 初始化一个d维空间的矩阵作为权重矩阵W'[d,V]
skip-gram神经网络包含一个巨大的权重矩阵。例如,300个特征,10000个单词字典,那么输出层和隐藏层都将有3M个权重。在一个大的数据集上进行训练是很难的,所以word2vec作者引入了一些调整来使训练变得可行。
1.负采样(negative sampling)
负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。
随机采样的方法即,假设现在共有N个unique样本,我们统计这N个样本的频率,从小到大得到(n1, n2, ..., nN),将频率进行累计归一化,则归一化的结果为(n1/sum, (n1+n2)/sum, ..., 1),归一化到(0,1)上。然后,在(0,1)上生成随机数,通过判断该随机数所属的区间,得到样本,若这个样本不为正样本,则保留下来作为负样本。这样采样即可以保证随机抽取,同时可以保证频率高的样本被抽到的可能性高。
2.层序softmax --------Hierarchical Softmax
Huffman Tree
中文名叫霍夫曼树/霍夫曼编码,是个二叉树(注意不是二叉搜索树),这部分内容比较简单,维基百科上也说的非常清楚,下面搬运一下维基百科上的例子:
示例:
霍夫曼树常处理符号编写工作。根据整组数据中符号出现的频率高低,决定如何给符号编码。如果符号出现的频率越高,则给符号的码越短,相反符号的号码越长。假设我们要给一个英文单字"F O R G E T"进行霍夫曼编码,而每个英文字母出现的频率分别列在Fig.1。
演算过程:
(一)进行霍夫曼编码前,我们先创建一个霍夫曼树。
- 将每个英文字母依照出现频率由小排到大,最小在左,如Fig.1。
- 每个字母都代表一个终端节点(叶节点),比较F.O.R.G.E.T六个字母中每个字母的出现频率,将最小的两个字母频率相加合成一个新的节点。如Fig.2所示,发现F与O的频率最小,故相加2+3=5。
- 比较5.R.G.E.T,发现R与G的频率最小,故相加4+4=8。
- 比较5.8.E.T,发现5与E的频率最小,故相加5+5=10。
- 比较8.10.T,发现8与T的频率最小,故相加8+7=15。
- 最后剩10.15,没有可以比较的对象,相加10+15=25。
最后产生的树状图就是霍夫曼树,参考Fig.2。

- 给霍夫曼树的所有左链接'0'与右链接'1'。
-
从树根至树叶依序记录所有字母的编码,如Fig.3。
![]()
上图输出层的树形结构即为Hierarchical Softmax。
每个叶子节点代表语料库中的一个词,于是每个词语都可以被01唯一的编码,并且其编码序列对应一个事件序列,于是我们可以计算条件概率
在开始计算之前,还是得引入一些符号:
1. :从根结点出发到达w对应叶子结点的路径
2. :路径中包含结点的个数
3. :路径
中的各个节点
4. :词w的编码,
表示路径
第j个节点对应的编码(根节点无编码)
5. :路径
中非叶节点对应的参数向量
于是可以给出w的条件概率:
这是个简单明了的式子,从根节点到叶节点经过了 个节点,编码从下标2开始(根节点无编码),对应的参数向量下标从1开始(根节点为1)。
其中,每一项是一个逻辑斯谛回归:
考虑到d只有0和1两种取值,我们可以用指数形式方便地将其写到一起:
我们的目标函数取对数似然:
将 代入上式,有:
这也很直白,连乘的对数换成求和。不过还是有点长,我们把每一项简记为:
怎么最大化对数似然函数呢?分别最大化每一项即可(这应该是一种近似,最大化某一项不一定使整体增大,具体收敛的证明还不清楚)。怎么最大化每一项呢?先求函数对每个变量的偏导数,对每一个样本,代入偏导数表达式得到函数在该维度的增长梯度,然后让对应参数加上这个梯度,函数在这个维度上就增长了。这种白话描述的算法在学术上叫随机梯度上升法,详见更规范的描述。
每一项有两个参数,一个是每个节点的参数向量 ,另一个是输出层的输入
,我们分别对其求偏导数:
因为sigmoid函数的导数有个很棒的形式:
于是代入上上式得到:
合并同类项得到:
于是 的更新表达式就得到了:
其中, 是学习率,通常取0-1之间的一个值。学习率越大训练速度越快,但目标函数容易在局部区域来回抖动。
再来 的偏导数,注意到
中
和
是对称的,所有直接将
的偏导数中的
替换为
,得到关于
的偏导数:
于是 的更新表达式也得到了。
不过 是上下文的词向量的和,不是上下文单个词的词向量。怎么把这个更新量应用到单个词的词向量上去呢?word2vec采取的是直接将
的更新量整个应用到每个单词的词向量上去:
总结
最后强调一下,word2vec一个NLP工具,它可以将所有的词向量化,这样词与词之间就可以定量的去度量他们之间的关系,挖掘词之间的联系。word2vec主要包含两个模型Skip-gram和CBOW。以及两种高效的训练方法负采样,层序softmax。
关于Word2Vec的详细介绍终于结束了,相信看完本文章你会理解Word2Vec的来龙去脉。下面读者可以查看下面的章节用TensorFlow来实现Word2Vec。


浙公网安备 33010602011771号