一、GloVe模型
基于统计的词向量模型以基于SVD分解技术的LSA模型为代表,通过构建一个共现矩阵得到隐层的语义向量,充分利用了全局的统计信息。然而这类模型得到的语义向量往往很难把握词与词之间的线性关系(例如著名的King、Queen、Man、Woman等式)。
基于预测的词向量模型则以基于神经网络的Skip-gram模型为代表,通过预测一个词出现在上下文里的概率得到embedding词向量。这类模型的缺陷在于其对统计信息的利用不充分,训练时间与语料大小息息相关。不过,其得到的词向量能够较好地把握词与词之间的线性关系,因此在很多任务上的表现都要略优于SVD模型。
既然两种模型各有优劣,那么能不能二者各取其长,构造一个更强大的词向量模型呢?
在GloVe的原始论文里,作者首先分析了Skip-gram模型能够挖掘出词与词之间线性关系的背后成因,然后通过在共现矩阵上构造相似的条件,得到一个基于全局信息的词向量模型——GloVe模型。
1.1 统计共现矩阵
共出矩阵其实很容易理解,假设现在有共现矩阵为 X
,则 X_i,j
的意义就是在整个语料库中,单词 i
和单词 j
共同出现在一个窗口中的次数。
例如有语料库:i love you but you love him i am sad
这个小小的语料库只有1个句子,涉及到7个单词:i、love、you、but、him、am、sad。
如果我们采用一个窗口宽度为5(左右长度都为2)的统计窗口,那么就有以下窗口内容:
以窗口5为例说明如何构造共现矩阵:
中心词为love,语境词为but、you、him、i,则:
使用窗口将整个语料库遍历一遍,即可得到共现矩阵X。
1.2 使用GloVe模型的原理
如果想利用全局的统计信息的话,那么必然需要将其纳入到词向量的训练过程中,最直接的方法当然是构建包含全局统计信息的损失函数。那么,该如何构建呢?
首先我们考虑共现矩阵的信息能不能用另外的方式来表示,使得我们可以通过网络学习。
如上面的共现矩阵表示形式,X_ij
表示了词j和词i所在的上下文中出现的次数,X_i
表示以词i为中心的上下文的所有词,那么我们就可以得到:
使用同样的计算过程,我们可以得到单词 k
出现在单词 j
语境中的概率。通过将两个概率相除,便可以得到如下结果:
通过研究最后一行的可以看出:
对于词 i,j,k
,如果k
在i
和j
的上下文中出现的次数比率太大或太小,这说明其中有相关性存在,而如果这个比值接近1,那么就没啥意义
也就是说,只要我们使用网络,让其学习这个概率,那么最后学习得到的词向量也就包含了共现矩阵的全局统计信息。
所以,现在的问题也就转化成了如何用网络或者说设计损失函数学习这一规律。
由这些信息直接构建损失函数有点困难,那么干脆我们由果索因,如果我们有这么一个网络可以做到我们所设想的事情,那么它比如可以写出如下的式子:
g函数就是我们的网络,也就是说,我们最后学到网络必然应该使得上式尽可能成立。那么,最自然的想法就是用差值来衡量两者的相近程度:
但这样的包含3个单词的损失函数是极难训练的,所以比如需要对g函数做一定的优化。
首先考虑的是 v_i
, v_j
直接的关系,可以想象由于 v_i
和 v_j
之间的差异才会使得上述规律存在,那么网络在学习用 v_i
、v_j
和 v_k
作为输入得到 ratio_i,j,k
时,必然会学习 v_i
, v_j
之间的差异,那么我们直接先用式子表示出v_i,v_j之间的差异不就可以减少网络学习的难度了吗?
由于词向量具有线性关系,也就是说向量空间是内在的线性结构,所以表示 v_i
, v_j
之间的差异最自然有效的方法就是做差。(PS:其实我觉得这边做差其实也就是为了简单,因为神经网络是一个很强的非线性模型,所以其完全可以在学习过程中修正只是做差所带来的差异。也就是说,我们这边做差只是帮网络简化了其学习过程,否则它可能还要试试更多的四则运算从而才能找到最后的结果。与其这样,不如我们直接就给出一个相对比较正确的差异表示方法,从而节省一些没必要的尝试过程)
又因为考虑到 ratio_i,j,k
是一个标量,而 v_i
、v_j
和 v_k
都是向量,那么从向量到标量最直接的方法也就是点乘:
这样我们也就表示出来g函数,但是仔细一看,这个损失函数还是很难训练。那么接着考虑,我们可以看出 ratio_i,j,k
是一个除法结构,那么作为等式的另一边,必然也应该可以表示成这样的除法结构。于是考虑通过引入exp函数做到这样的操作:
然后就发现找到简化方法了:只需要让上式分子对应相等,分母对应相等。
通过观察可以发现,分子分母的形式是相似的,也就是说我们完全可以通过统一的形式来学习:
注意:这边下标表示替换了一下,与上面的表示方法并不相同,不要对号入座
通过对两边去对数,我们可以将损失函数简化成:
但仔细深究就会发现这个损失函数是有问题的,由上述推导可以得到:
对于这样的向量乘法来说,互换下标不会改变其最后的结果,但P互换则不相等。我们将P_i,j展开可以得到:
我们发现前一项刚好下标互换不会改变结果,那么我们可以学习这一项:
于是损失函数就变成了:
该损失函数的一个主要缺点为它认为所有的共现词权重相等,即使很少出现或没有出现的词,所以为了克服这一缺点,使用了加权最小二乘回归模型。也就是说基于出现频率越高的词对其权重应该越大的原则,在损失函数中添加权重项,于是代价函数进一步完善:
具体权重函数应该是怎么样的呢?
首先应该是非减的,其次当词频过高时,权重不应过分增大,作者通过实验确定权重函数为:
二、fastText 模型
2.1 基本原理
fastText 模型输入一个词的序列(一段文本或者一句话),输出这个词序列属于不同类别的概率。序列中的词和词组组成特征向量,特征向量通过线性变换映射到中间层,中间层再映射到标签。fastText 在预测标签时使用了非线性激活函数,但在中间层不使用非线性激活函数。
文本分类 情感分析fastText 模型架构和 Word2Vec 中的 CBOW 模型很类似,都采用了Hierarchical softmax来对大数据集进行加速。FastText根据语料中每个标签出现的次数构造一颗Huffman树。不同之处在于,fastText 预测标签,而 CBOW 模型预测中间词。
fastText 模型2.2 n-gram特征
FastText使用了n-gram来给文本添加额外的特征来得到关于局部词顺序的部分信息 。对于句子:“我 喜欢 喝 咖啡”, 如果不考虑顺序,那么就是每个词,“我”,“喜欢”,“喝”,“咖啡”这五个单词的word embedding求平均。如果考虑2-gram, 那么除了以上五个词,还有“我喜欢”,“喜欢喝”,“喝咖啡”等词。“我喜欢”,“喜欢喝”,“喝咖啡”这三个词就作为这个句子的文本特征。
但为了提高效率,实际中会过滤掉低频的 N-gram,否则将会严重影响速度的话。
使用n-gran feature有如下优点:
-
为罕见的单词生成更好的单词嵌入
-
在词汇单词中,即使单词没有出现在训练语料库中,它们也可以从字符级n-gram中构造单词的向量
-
采用n-gram额外特征来得到关于局部词顺序的部分信息
但是也存在一些缺点: 随着语料库大小的增长,内存需求也会增长
论文中作者提出的解决方案是:
-
过滤掉出现次数过少的词 。
-
使用hash存储。
-
由采用字粒度变为采用词粒度
2.3 fastText和word2vec的区别
-
模型的输出层:word2vec的输出层,对应的是每一个term,计算某term的概率最大。而fasttext的输出层对应的是 分类的label。不过不管输出层对应的是什么内容,起对应的vector都不会被保留和使用
-
模型的输入层:word2vec的输出层,是 context window 内的term。而fasttext对应的整个sentence的内容,包括term,也包括 n-gram的内容
-
Wordvec的目的是得到词向量,该词向量最终是在输入层得到,输出层对应的 h-softmax也会生成一系列的向量,但最终都被抛弃,不会使用。
fasttext则充分利用了h-softmax的分类功能,遍历分类树的所有叶节点,找到概率最大的label(一个或者N个)
三、评测方法
有两种方法:Intrinsic(内部) VS extrinsic(外部)
Intrinsic:专门设计单独的试验,由人工标注词语或句子相似度,与模型结果对比。好处是是计算速度快,但不知道对实际应用有无帮助。有人花了几年时间提高了在某个数据集上的分数,当将其词向量用于真实任务时并没有多少提高效果,想想真悲哀
Extrinsic:通过对外部实际应用的效果提升来体现。耗时较长,不能排除是否是新的词向量与旧系统的某种契合度产生。需要至少两个subsystems同时证明。这类评测中,往往会用pre-train的向量在外部任务的语料上retrain
网友评论