全局向量的词嵌入(GloVe)
设 pij=P(wj∣wi) 即词 wj 在出现在词 wi 上下文中的概率(用大型语料库中共现的频率来估计)。一种想法是选取一些背景词 w 用 P(w∣wc) 构成的向量来刻画 wc,用一个在教材上的例子:
w= |
solid |
gas |
water |
fashion |
p1=P(w∣ice) |
0.00019 |
0.000066 |
0.003 |
0.000017 |
p2=P(w∣steam) |
0.000022 |
0.00078 |
0.0022 |
0.000018 |
p2p1 |
8.9 |
0.085 |
1.36 |
0.96 |
- 与 ice,steam 同时无关以及同时有关的词作为上下文词,两个条件概率的比值接近于 1。
- 如果上下文词仅与其中一个相关,但与另一个不太相关,那么两个条件概率要么很大,要么很小。
条件概率的比值能很好地刻画词与词之间的关系。因此我们希望找一个关于词向量的函数来拟合这样的概率比值。设 wi 为中心词,wj 和 wk 为上下文词,vi 表示 wi 的中心词向量,uj 和 uk 分别表示 wj 和 wk 的上下文词向量。那么我们希望寻找函数 f,使得它能够估计 pikpij:
f(uj,uk,vi)≈pikpij
我们希望 f 能满足一些性质:
- f 的值为标量
- f(uk,uj,vi)⋅f(uj,uk,vi)=1,即交换 j,k 的位置满足某种 “对称性”
一种想法是令 f(uj,uk,vi)=g((uj−uk)⋅vi) 再由第二条性质选取 g(x)=ex,然后得到:
f(uj,uk,vi)=exp(uk⋅vi)exp(uj⋅vi)≈pikpij
然后有 exp(uj⋅vi)≈αpij,其中 α 是某个与 i,j,k 有关的常数。对两边取对数,然后将 pij 替换为频率的比值,得到 uj⋅vi≈logα+logxij−logxi。我们添加中心词偏置 bi 以及上下文偏置 cj 来拟合 logα−logxi。于是得到最终的式子:
uj⋅vi+bi+cj≈logxij
对于损失函数,我们使用加权平方损失函数:
L=i∈V∑j∈V∑h(xij)(uj⋅vi+bi+cj−logxij)2
其中 h:N↦[0,1] 为权重函数,用于防止高频词占据较大的权重,一种例子是:
h(x)=⎩⎪⎪⎨⎪⎪⎧0(x/100)0.751(x=0)(x<100)(x⩾100)
使用预训练的 GloVe
在 torchtext
包中可以找到预训练的嵌入模型:
1 2 3 4
| import torch import torchtext.vocab as vocab
print(vocab.pretrained_aliases.keys())
|
输出:
1
| dict_keys(['charngram.100d', 'fasttext.en.300d', 'fasttext.simple.300d', 'glove.42B.300d', 'glove.840B.300d', 'glove.twitter.27B.25d', 'glove.twitter.27B.50d', 'glove.twitter.27B.100d', 'glove.twitter.27B.200d', 'glove.6B.50d', 'glove.6B.100d', 'glove.6B.200d', 'glove.6B.300d'])
|
GloVe 的命名大致规范为 模型.(数据集.)数据集词数.词向量维度
。
通过
1
| glove = vocab.GloVe(name = '6B', dim = 50, cache = './.vector_cache')
|
可以获取 glove.6B.50
的嵌入模型。如果不指定 cache
的值的话,默认缓存在 ./.vector_cache
。返回的实例主要有三个属性:
stoi
:词到索引的字典
itos
:索引到词的列表
vectors
:词向量
不知道为什么我电脑上一直 HTTP Error 404。可以在这个地方找到国内的服务器下载的地址,或者也可以直接从这个地方下载。然后把压缩包改名为 glove.6B.zip
,里面放 glove.6B.50d.txt
就可以用了。
看了一下那个文件,其实它每行前面的先是词(也可能是标点),后面是对应的向量。感觉其实自己写一个嵌入的字典也不是很麻烦。
子词嵌入(fastText )
在英语中,例如 helps
、helped
都是 help
的变形,语言的变形和含义有着类似的关系,但是 word2vec 和 GloVe 都没有考虑词内部的结构进行探讨。为了使用形态信息,fastText 模型提出一种子词嵌入的方法,其中每个子词是由 n 个字符组成的子串。
例如,单词 where
以及 n=3,首先在 where
首尾添加特殊字符得到 <where>
,然后再拆分得到:<wh
、whe
、her
、ere
和 re>
。首尾添加的特殊字符使得可以区分整词 <her>
和子词 her
。
在 fastText 中,对于任意一个词 w,用 Gw 表示 w 所有长度在 [3,6] 之间的字词构成的集合,为所有子词分配一个向量 z,词 w 的中心词向量被定义为其子词向量的和:
vw=g∈Gw∑zg
fastText 中剩余部分与跳元模型相同。但是与跳元模型相比,fastText 的词量更大,参数也更多,也有着更高的计算复杂度。但是一些罕见词能在 fastText 中获得更好的向量表示。