1 Word2Vec模型的负采样方法
上一节讲的word2vec的模型,是一个基于naive softmax的word2vec的基础模型,因为复杂度高等原因,在实际的word2vec中会基于其他的一些方法来实现,负采样(negative sampling)就是其中的一个
1.1 negative sampling的目的
上一节的笔记最后提到,如果使用naive softmax的,且使用随机梯度下降的话,那么最后对的梯度的表达式是
这其中,k是一个1到V之间的随机数。虽然通过梯度下降的方法将复杂度降低了一个数量级,但是现在分母上仍然需要遍历语料库,这样造成的时间开销依然非常大;因此出于性能的考虑,在实际中一般不使用这种基于naive softmax方法的word2vec
1.2 negative sampling的形式
基于negative sampling的word2vec模型的目标函数如下:
其中称为sigmoid函数,经常会遇到
现在的目标是通过调整参数来最大化
(注意是最大化不是最小化)
首先大体解释一下这个式子,其中是以每一个位置作为中心词时的一个得分,而我们要优化的目标函数
是每一个位置的词作为中心词时得分的一个平均值,其中T是这段文本当中单词的个数
再来从意义上解释一下这个式子,我们看的前半段,
和
是窗口中的一对上下文和中心词,我们自然希望他们的内积越大越好,而根据函数的单调性,他们的内积越大则
越大,那么
越大,优化的目标与我们希望的方向一致。对于
的后半段这一个加和,表达的含义是:我们重复k次,每次根据一个分布
取出一个1到V之间的编号j,我们基本上可以认为这个向量
对应的词和
对应的词不是中心词和上下文的关系,所以我们希望他们的内积尽量小(这就是负取样的核心),他们的内积越小那么
就越大,因此
越大,与我们希望的方向一致。因此,我们在优化使
变小的过程中,就会让本身是上下文与中心词关系的词的内外向量内积变大,不是上下文和中心词关系的变小。
剩下没有说的就是分布了,其实这个分布的方式很简单:每次根据分布产生一个单词,这个单词是w的概率是
,count(w)是词w在这篇文章中出现的次数
最后,虽然的意义上面已经指出,看起来也是合理的,但是突然给出这样一个式子看来有点过于主观。其实,
的形式就是一个不折不扣的logistic regression的优化的目标的形式,logistic regression的优化目标的形式的表示当中有一个是这样的:
其中是1或-1,表示样本的标签是或者不是,这样一看,
是不是就是用具体的符号表示的一个logistic regression?在负采样过程中,
和
对应单词组成的上下文和中心词对应标签的y=1,而根据分布P(w)得到的
和
对应单词不是上下文和中心词关系,所以y=-1
2 基于co-occurrence matrix的词嵌入方法
在word2vec模型中,我们针对中心词和他窗口中的一个上下文进行一次梯度更新,我们也可以理解成针对一对共同出现的单词进行梯度更新;那么我们对于共同出现的一组单词,能不能直接记录他们共同出现的次数,来实现词嵌入呢?事实上在word2vec出现之前,基于这种统计共现次数的词嵌入方法就已经存在了
2.1 co-occurrence matrix(共现矩阵)
共现矩阵的定义很简单:共现矩阵的一行和一列都代表一个单词,对于一个共现矩阵,
表示单词i和单词j共同出现的次数,显然对于共现矩阵有
,那么“共同出现”是怎么定义的呢?
第一种类似word2vec,就是对于每个单词作为中心词有一个窗口,中心词和窗口中单词可以记为“共同出现”一次,这样得到的共现矩阵得到的比较多的会是关于语法的(sytactic)和语义的(semantic)的信息。sytactic和semantic在NLP的文章中经常会出现,这里解释一下:sytactic指的是语法上的关系,比如通过模型学习到big、bigger、biggest之间的关系;semantic指的是语义上的关系,比如通过模型学习到woman和man的关系
举一个例子,假设窗口长度为1,文本总共有三句话:
I like deep learning.
I like NLP.
I enjoy flying.
那么他们的共现矩阵会是这样:
第二种“共同出现”的范围则是整段文本,的扫一次文章,扫的过程中两个词都被认为是“共同出现”一次。这样得到的共现矩阵得到的比较多的是关于主题的信息。
2.2 共现矩阵的奇异值分解
当语料库中词的数量比较多的时候,共现矩阵需要相当大的内存进行存储,这在很多时候是不好做到的,所以我们要想办法用较小的空间存储共现矩阵中的信息
一个比较好的办法是对共现矩阵进行奇异值分解(SVD)
严格的奇异值分解是这样定义的:对于一个矩阵,可以分解为如下的形式:
其中若是一个n*m矩阵,则
是一个n*n的矩阵,
是一个n*m的矩阵,
是一个m*m的矩阵,且
、
都是正交矩阵(任两列向量相互正交),
是一个对角矩阵(只有对角线上元素非0)
对角矩阵对角线上元素称为矩阵
的奇异值,矩阵
的列向量称为左奇异向量,矩阵
的列向量称为右奇异向量
上面是奇异值分解的定义,而奇异值分解之后有如下的性质:
①矩阵的左奇异向量是
的特征向量,对应的特征值是
的非零奇异值;矩阵
的右奇异向量是
的特征向量,对应的特征值也是
的非零奇异值
②在物理意义上,矩阵的奇异值与奇异向量记录了一个矩阵的主要特征,而且越大的奇异值对应的奇异向量就越能反映矩阵的特征;但是,很多情况下绝大多数奇异值都比较小,只有少数比较大,也就是说只有少数的特征向量反映的矩阵的物理意义比较明显
上面简单介绍了什么是SVD以及SVD的性质,但是还是不能减小存储的空间(变成三个矩阵之后消耗的空间更大了)
我们想要做的,是把矩阵按照下面这张图的方式进行奇异值分解:
其中,k是一个远小于n和m的数,如果能实现这样的分解,那么的确可以减小空间,但问题是这并不满足SVD的形式,那么这是怎么实现的呢?
遗憾的是,在我查阅的资料中并没有确凿的证据描述这是怎么实现的,但根据我自己的思考和推测,应该是这样子的(如有问题,欢迎指出):
矩阵原本是n*m的,
原本是n*n的,
原本是m*m的。对于矩阵
的奇异值,我们选择其中最大的k个值,舍弃与这k个值无关的行和列,便得到了现在k*k的矩阵
;在舍弃行和列的过程中,如果舍弃的行和列包含了某一个奇异值,那么我们就放弃其对应的左奇异向量和右奇异向量;放弃一个左奇异向量,代表
少了一列,最终
变成了n*k的;放弃一个右奇异向量,代表
少了一列,也就是
少了一行,最终
变成k*m的
2.3 SVD到词向量
通过2.2一节,我们实现了用比较小的空间保存了共现矩阵的巨大多数特征的任务,这一任务是通过SVD实现的,那么下一步就是怎么得到一个词向量的问题了
假设共现矩阵按上述分解后共有k个奇异值,我们想要的词向量是d(d<=k)维的,那么我们选择这k个奇异值中最大的d个,找到左奇异向量中对应的向量们,也就是矩阵对应的列,假设说现在d=4,对应的是
的第1、2、4、7列;对于
来说,每一行代表一个单词的信息,那么对于第i个单词,通过这种方式得到的词向量就是
以上,就是基于共现矩阵得到词向量的方式
再来看2.1中的例子,如果我们想要由这些单词得到2维的词向量,并把得到的词向量绘制在平面上,得到的效果就是这样的:
可以看到,视觉上距离较近的词,他们的词义之间往往有着一定的联系(当然在这个例子里面并不显然,毕竟参与训练的文本实在太少了)
2.4 共现矩阵的可改进之处
像it、has、the这一类单词出现的太过频繁,会在最终结果上产生一个比较明显的影响,但是我们知道,这一类词本身并没有包含太丰富明确的词义;另一方面,有些词可能出现的次数比较少,也就是所谓的低频稀有词,他们有明确的词义,比如说eleutherodactylus(离趾蟾蜍),可能因为无实义的高频词太多,反而堙没了他们的词义,对此我们可以用下面的办法适当地改变共现矩阵:
方法一:限制共现矩阵中每个元素的大小,比如限制每个元素最大为100,超过了也按100处理
方法二:对于一个中心词窗口中的上下文,为他们设置不同的权重,比如离中心词近的权重大,离的远的权重小
3 GloVe模型
截止目前,我们一共学习了两种不同类型的词嵌入方法,一种是基于共现矩阵的方法,另一种是基于神经网络的方法(skip-gram为代表的);这两种方法可以说是各有利弊,前者训练较后者更为快速高效,而且复杂度比较稳定;后者较前者虽然效率有差距,但这样实现的词嵌入向量能够适应更多的下游问题。现在,我们考虑把这两种基本的方法结合起来,就得到了GloVe模型
GloVe模型全称是Global Vector模型,这个模型中我们要最小化的代价函数是这个样子的:
其中,是共现矩阵,
是共现矩阵中第i行第j列的数值
这里的和
不是之前讲的上下文和中心词向量,在这个模型中,每个单词x对应两个向量
和
,他们的含义是类似的,用两个向量表示一个单词纯粹是因为这样得到的效果更好
代价函数中函数的形式是这样的:
课件里取的为1,函数图像如下:
注意这里的和原论文中的形式不太一样,但课上老师提到按照课件中的形式来做效果更好
我们最小化之后,就得到了每一个单词x对应的
和
,最终x对应的向量
就是把这两个向量加起来的结果,即
4 词嵌入方法的评估
我们已经学习了很多种词嵌入的方法,那么我们要通过什么样的方法来评估哪一种词嵌入方法的效果更好呢?词嵌入的评估手段主要分两种,即内部评估(intrinsic evaluation)和外部评估(extrinsic evaluation)
4.1 内部评估
通俗地讲,内部评估就是在不绕太多弯的前提下,用简单直观地方式评估某一种词嵌入方式是否准确地挖掘出了单词的语义和语法信息
4.1.1 Word Vector Analogies
Word Vector Analogies,即单词向量类比,是一个典型的内部评估方法
Word Vector Analogies的主要内容是这样的:假如现在有a、b、c三个单词,我希望利用词嵌入得到的所有词向量,找到一个单词d,使得d相对于c的关系就好比b相对于a的关系;举个例子,我希望找到一个单词相对king的关系,就好比woman相对于man的关系,那么正确答案就是queen
那么具体来讲是怎么做的呢?
我根据我的词嵌入算法,得到单词a、b、c对应的词向量、
、
,现在我要找到这样的一个单词编号d,使其满足
那么单词d就是通过当前词嵌入算法得到的类比向量
这种方法之所以合理,是因为对于关系类似的两对单词,他们的差值向量大概也是类似的(如下图),因此就是以
为起点,走过一个类似
的向量后得到的位置,就是我们期望的单词向量的位置,所以我们只要找一个和他内积最大的,也就是最为接近的,就可以认为是通过这个词嵌入算法得到的结果
这里再强调一下,Word Vector Analogies是一个评估的方法,而不是一个训练的任务,我们有专门的测试集,用来评估每种词嵌入算法做Word Vector Analogies的正确率,并以此为衡量词嵌入算法优劣的指标
4.1.2 Cosine Similarity
相对于Word Vector Analogies,另一个更简单粗暴的方式是计算余弦相似度
用于评估的测试集给出了很多对单词以及他们的余弦相似度,对于给出的每一对单词,我们计算他们的余弦相似度,如果余弦相似度和测试集给出的结果相比,差距越小说明这个词嵌入方法越好
4.2 外部评估
词嵌入方法的外部评估,主要指使用了某一种词向量算法之后,在下游问题上的表现如何,下游问题指的是诸如实体识别、机器翻译、情绪分析等具体的应用。当下游问题的模型确定之后,我们使用不同的词嵌入方法,看到了不一样的效果,以此可以得出哪些词嵌入方法能更加适应这个下游问题的结论