本节课继续讲授word2vec模型的算法细节,并介绍了一种新的基于共现矩阵的词向量模型——GloVe模型。最后,本节课重点介绍了word2vec模型评估的两种方式。

Skip-gram模型

上节课,我们介绍了一个十分简单的word2vec模型。模型的目标是预测word oo出现在另一个word cc的上下文语境里的条件概率:

p(o|c)=exp(uTovc)Ww=1exp(uTwvc)p(o|c)=exp(uoTvc)∑w=1Wexp(uwTvc)


其中,向量uouo被称为word oo的outside vector;向量vcvc被称为word cc的inside vector。

模型的损失函数是一个对数似然概率:

J(θ)=1Tt=1T?mjm,j0logp(wt+j|wt)J(θ)=1T∑t=1T∑?m≤j≤m,j≠0log?p(wt+j|wt)


后面我们会看到这个损失函数的物理意义。

我们通常用一个向量θθ表示模型的所有参数(这里是词典中每个word的uuvv向量)。显然这是一个维度巨大的长向量(θR2dVθ∈R2dV)。然而,在用SGD(随机梯度下降法)求解模型的参数时,对于每一个时间窗口,我们至多仅有2c?12c?1个单词需要计算。因此,θθ的梯度?θJt(θ)?θJt(θ)是一个极其稀疏的向量!

为此,在word2vec模型里,我们通常用一个叫做embedding matrix的矩阵存储模型的参数。该矩阵的大小为d×Vd×V,每一列对应着词典中一个word的词向量。借助这个hash词表,我们可以只对当前训练时出现的词向量进行更新。

然而,这个简单的word2vec模型的训练却并不简单。原因在于计算损失函数的梯度时需要用到归一化的条件概率——而正是这个归一化成为了模型训练的瓶颈。想象一个百万量级的词典,每一步训练我们都需要计算上百万次词向量的内积——显然,这是无法容忍的。

因此,Mikolov在2013年那篇著名的论文里提出了一种负采样(Negative Sampling)的似然函数,避免了归一化概率的计算:

Jt(θ)=logσ(uTovc)+i=1KEjP(w)[logσ(?uTjvc)]Jt(θ)=log?σ(uoTvc)+∑i=1KEj~P(w)[log?σ(?ujTvc)]


其本质是训练一个二分类的逻辑回归函数,用于判断一对词是来自真实语料环境还是采样自一个随机的噪声分布。KK是模型的超参数,决定负采样的个数。σ(x)=11+e?xσ(x)=11+e?x是逻辑回归函数,也被称为Sigmoid函数。注意到σ(?x)=1?σ(x)σ(?x)=1?σ(x)。 P(w)P(w)通常取为U(w)34U(w)34。幂次项对超高频的word起到了下采样的作用。

基于这个似然函数,Mikolov在他的word2vec工具包里提供了两种模型:Skip-gram和CBoW。这两个模型都是一个log-bilinear的浅层神经网络结构。区别在于,Skip-gram是用一个center word预测其context里的word;而CBoW是用context里的所有word去预测一个center word。显然,前者对训练数据的利用更高效,因此,对于较小的语料库,Skip-gram是更好的选择。

GloVe模型

在上节课最后,我们比较了基于统计的词向量模型和基于预测的词向量模型。前者以基于SVD分解技术的LSA模型为代表,通过构建一个共现矩阵得到隐层的语义向量,充分利用了全局的统计信息。然而这类模型得到的语义向量往往很难把握词与词之间的线性关系(例如著名的King、Queen、Man、Woman等式)。后者则以基于神经网络的Skip-gram模型为代表,通过预测一个词出现在上下文里的概率得到embedding词向量。这类模型的缺陷在于其对统计信息的利用不充分,训练时间与语料大小息息相关。不过,其得到的词向量能够较好地把握词与词之间的线性关系,因此在很多任务上的表现都要略优于SVD模型。

既然两种模型各有优劣,那么能不能二者各取其长,构造一个更强大的词向量模型呢?这就是接下来要介绍的GloVe模型。

在GloVe的原始论文里,作者首先分析了Skip-gram模型能够挖掘出词与词之间线性关系的背后成因,然后通过在共现矩阵上构造相似的条件,得到一个基于全局信息的词向量模型——GloVe模型。

GloVe模型的损失函数是:

J(θ)=12i,j=1Wf(Pij)(uTivj?logPij)2J(θ)=12∑i,j=1Wf(Pij)(uiTvj?log?Pij)2


其中,f(x)f(x)是一个截断函数,以降低高频词对模型的干扰。

与Skip-gram模型相比,GloVe在充分利用了语料库的全局统计信息的同时,也提高了词向量在大语料上的训练速度(一个共现矩阵的遍历要比整个语料库的遍历容易的多)。而与传统的SVD技术相比,SGD的训练也更加简单高效。同时,GloVe得到的词向量更能把握住词与词之间的线性关系。

模型的评估

在NLP的研究领域里,一个模型的评估通常有两种方式:Intrinsic和Extrinsic。

Intrinsic评估关注的是模型在一个特定子任务上的表现。子任务的设计使得Intrinsic的评估快速便捷,同时有助于我们更好地理解模型内在的性质。不过,要注意的是,除非子任务被设计为与我们的最终目标有一定的联系,否则,模型在子任务上的评估结果并不具有太大的意义。

Extrinsic评估则关注的是模型在一个具体任务上的表现。比如情感分析或是机器翻译。此时,我们关注的模型通常只是一个更复杂模型里的一部分。因此,Extrinsic评估一般比较耗时。但是相比于Intrinsic评估更具有参考意义。

Intrinsic评估

对于词向量模型,一个常用的Intrinsic评估是向量类比(word vector analogies)。它评估了一组词向量在语义和句法上表现出来的线性关系。具体来说,给定一组词(a, b, c, d),我们要验证的是:d=argmaxi(xb?xa+xc)Txi||xb?xa+xc||d=arg?maxi(xb?xa+xc)Txi||xb?xa+xc||,即dd是与向量(xb?xa+xc)(xb?xa+xc)的cosine距离最近的词。

Mikolov在他的word2vec开源工具包里也提供了用于word analogy评估的数据集。例如国家与首都的类比数据,时态或是比较级的类比数据。

借助于Intrinsic评估,我们也可以方便快捷地对模型的超参数(Hyperparameters)进行选择。例如向量的维度,context window的大小,甚至是模型的选择。

Extrinsic评估

值得注意的是,即使一些模型在人为设定的Intrinsic任务上表现较弱,并不能说明它们在具体的真实任务中毫无优势。Intrinsic评估的主要作用是对模型的超参数进行初步的调整和选择(这种模型选择在Extrinsic任务上往往极为耗时)。而评估模型的优劣还是要看它在Extrinsic任务上的表现。

对于词向量模型,常见的Extrinsic任务是对词向量进行分类。例如命名实体识别(NER)和情感分析。理论上,如果我们习得的词向量足够精确,那么语义或句法上相近的词必然分布在同一片向量空间。这就使得基于词向量的分类更加准确。

为此,我们引入专门处理多分类问题的Softmax函数。这个函数是Sigmoid函数的一般形式;它给出了每个类别在输入特征xx下的归一化条件概率。在后面的课程中,我们会经常用到这个函数:

p(y|x)=exp(Wyx)Cc=1exp(Wcx)p(y|x)=exp(Wyx)∑c=1Cexp(Wcx)


(这其实就是上节课我们介绍word2vec模型时提到的条件概率p(o|c)p(o|c)!因此,矩阵WW也可以被认为是分类label yy的主题向量。)

由于Softmax的输出是一个概率分布,因此,我们通常用交叉熵(Cross Entropy)来定义Softmax的损失函数。

交叉熵可以用两个分布的KLKL散度表达:

H(p,q)=H(p)+DKL(p||q)H(p,q)=H(p)+DKL(p||q)


其中,pp是真实的概率分布,qq是我们估计的概率分布。DKL(p||q)DKL(p||q)是一个非对称的变量,它定义了这两个分布的“距离”:

DKL(p||q)=c=1Cp(c)logp(c)q(c)DKL(p||q)=∑c=1Cp(c)log?p(c)q(c)


因此,最小化两个分布的交叉熵,等价于最小化这两个分布的KLKL散度距离。

对上式化简,我们得到交叉熵一个更直接的定义:

H(p,q)=?c=1Cp(c)logq(c)H(p,q)=?∑c=1Cp(c)log?q(c)


在单分类问题中,一条训练样本对应的pp是一个one-hot向量。因此,H(p,q)H(p,q)可以进一步简化为:

H(p,q)=?logq(y=c|x)H(p,q)=?log?q(y=c|x)


其中,p(c)=1p(c)=1。(对这个损失函数可以直观地理解为最大化目标label的对数似然概率)

最后,在用Extrinsic任务训练Softmax权重WW时,有一个问题值得考虑:我们是否也要同时对embedding的词向量进行调整?答案是,it depends。微调embedding的词向量固然使得模型能够更好地拟合训练数据,但如果训练数据不是足够多,对部分词向量的微调可能会破坏整个向量空间原有的几何结构,而使得模型的泛化能力反而变差了。

分类: 课程笔记