Glove和fastText

2020-04-10 09:43:17 浏览数 (1)

本文介绍两种更新一点的词向量,它们分别是2014年由Stanford团队发表的Glove和2017年由Facebook团队发表的fastText

Glove

Glove使用了词与词之间的共现(co-occurrence)信息。我们定义X为共现词频矩阵,其中元素x_{ij}表示词j出现在词i的环境(context)的次数。这里的"环境"有多种定义。举个例子,在一段文本序列中,如果词j出现在词i左边或者右边不超过10个词的距离,我们可以认为词j出现在词i的环境一次。令x_i=sum_kx_{ik}为任意词出现在词i的环境的次数。那么

P_{ij}=P(jmid i)=frac{x_{ij}}{x_i}

为词j出现在词i的环境的概率。这一概率也称为词i和词j的共现概率

共现概率比值

Glove论文里展示了以下一组词对的共现概率与比值

$w_k$

solid

gas

water

fashion

$p_1=P(w_kmid ice)$

0.00019

0.000066

0.003

0.000017

$p_2=P(w_kmid ice)$

0.000022

0.00078

0.0022

0.000018

$p_1/p_2$

8.9

0.085

1.36

0.96

我们可以观察到以下现象:

  • 对于与ice相关而与steam不相关的词k,例如k=solid,我们期望共现概率比值frac{P_{ik}}{P_{jk}}较大,例如上面最后一栏的8.9
  • 对于与ice不相关而与steam相关的词k,例如k=gas,我们期望共现概率比值frac{P_{ik}}{P_{jk}}较小,例如上面最后一栏的0.085
  • 对于与ice和steam都相关的词k,例如k=water,我们期望共现概率比值frac{P_{ik}}{P_{jk}}接近1,例如上面最后一栏的1.36
  • 对于与ice和steam都不相关的词k,例如k=fashion,我们期望共现概率比值frac{P_{ik}}{P_{jk}}接近1,例如上面最后一栏的0.96

由此可见,共现概率比值能比较直观的表达词之间的关系。Glove试图用有关词向量的函数来表达共现概率比值

用词向量表达共现概率比值

Glove的核心在于使用词向量表达共现概率比值。而任意一个这样的比值需要三个词ijk的词向量。对于共现概率P_{ij}=P(jmid i),我们称词i和词j分别为中心词和背景词。我们使用boldsymbol{v}boldsymbol{tilde {v}}分别表示中心词和背景词的词向量

我们可以用有关词向量的函数f来表达共现概率比值:

f(boldsymbol{v}_i,boldsymbol{v}_j,boldsymbol{tilde{v}}_k)=frac{P_{ik}}{P_{jk}}

需要注意的是,函数f可能涉及的并不唯一。首先,我们用向量之差来表达共现概率的比值,并将上式改写成

f(boldsymbol{v}_i-boldsymbol{v}_j,boldsymbol{tilde{v}}_k)=frac{P_{ik}}{P_{jk}}

由于共现概率比值是一个标量,我们可以使用向量之间的内积把函数f的自变量进一步改写

f((boldsymbol{v}_i-boldsymbol{v}_j)^Tboldsymbol{tilde{v}}_k)=frac{P_{ik}}{P_{jk}}

由于任意一对词共现的对称性,我们希望以下两个性质可以同时被满足:

  • 任意词作为中心词和背景词的词向量应该相等:对任意词iboldsymbol{v}_i=boldsymbol{tilde{v}}_i
  • 词与词之间共现次数矩阵X应该对称:对任意词ijx_{ij}=x_{ji}

为了满足以上两个性质,一方面我们令

f((boldsymbol{v}_i-boldsymbol{v}_j)^Tboldsymbol{tilde{v}}_k)=frac{f(boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k)}{f(boldsymbol{v}_j^Tboldsymbol{tilde{v}}_k)}

并得到f(x)=exp(x)。以上两式右边联立

exp(boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k)=P_{ik}=frac{x_{ik}}{x_i}

上式两边取对数可得

boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k=log(x_{ik})-log(x_i)

另一方面,我们可以把上式中的log(x_i)替换成两个偏移项之和b_i b_k,得到

boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k=log(x_{ik})-b_i-b_k

将索引ik互换,我们可以验证对称性的两个性质可以同时被上式满足

因此,对于任意一对词ij,用它们的词向量表达共现概率比值最终可以被简化为表达他们共现词频的对数:

boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k b_i b_k=log(x_{ik})
损失函数

上式中的共现词频是直接在训练数据上统计得到的,为了学习词向量和相应的偏移项,我们希望上式中的左边与右边越接近越好,给定词典大小V和权重函数f(x_{ij}),我们定义损失函数为

sum_{i,j=1}^{V}f(x_{ij})(boldsymbol{v}_i^Tboldsymbol{tilde{v}}_k b_i b_k-log(x_{ik}))^2

对于权重f(x),一个建议的选择是,当x<cc=100),令f(x)=(x/c)^a(例如a=0.75),反之令f(x)=1。需要注意的是,损失函数的计算复杂度与共现词频矩阵X中非零元素的数目呈线性关系。我们可以从X中随机采样小批量非零元素,使用随机梯度下降迭代词向量和偏移项。当所有词向量学习得到后,Glove是用一个词的中心词向量与背景词向量之和作为该词的最终词向量

关于Glove的一些公式推导,其实并不严谨,它只是提出了一些设计思路,为了满足那两个条件,共现词频应该设计成什么样。所以如果某一步推导看不懂也很正常,忽略过去就行了,只要知道最终的损失函数的性质就行

fastText

fastText在使用负采样的skip-gram模型基础上,将每个中心词视为子词(subword)的集合,并学习子词的词向量

以where这个词为例,设子词为3个字符,它的子词包括"<wh"、"whe"、"her"、"ere"、"re>"和特殊子词(整词)"<where>",其中"<"和">"是为了将作为前后缀的子词区分出来。而且,这里的子词"her"与整词"<her>"也可被区分。给定一个词mathcal{G}_{w}取出。假设词典中任意子词g的子词向量为boldsymbol{z}_g,我们可以把使用负采样的skip-gram模型的损失函数

-logP(w_omid w_c)=-logfrac{1}{1 exp(-boldsymbol u_o^Tboldsymbol{v}_c)}-sum_{k=1,w_ksim P(w)}^Klogfrac{1}{1 exp(boldsymbol u_{i_k}^Tboldsymbol{v}_c)}

直接替换成

-logP(w_omid w_c)=-logfrac{1}{1 exp(-boldsymbol u_o^Tsum_{gin mathcal{G}_{w_c}}boldsymbol{z}_g)}-sum_{k=1,w_ksim P(w)}^Klogfrac{1}{1 exp(boldsymbol u_{i_k}^Tsum_{gin mathcal{G}_{w_c}}boldsymbol{z}_g)}

我们可以看到,原中心词向量被替换成了中心词的子词向量的和。与整词学习(word2vec和Glove)不同,词典以外的新词的词向量可以使用fastText中相应的子词向量之和

fastText对于一些特定语言较重要,例如阿拉伯语、德语和俄语。例如,德语中有很多复合词,例如乒乓球(英文table tennis)在德语中叫"Tischtennis"。fastText可以通过子词表达两个词的相关性,例如"Tischtennis"和"Tennis"

如果遇到一个新词,对于fastText来说,它可以从训练集中找出这个新词的所有子词向量,然后做个求和,就能算出这个新词的词向量了

0 人点赞