Glove向量训练步骤:
1. 构建共现矩阵
假设共现矩阵为X,每个元素为: ,其表示的意义是:在整个语料库中,单词j和单词i共同出现在一个窗口中的次数。这里注意:一般而言,这个次数的数量是整数,但是Glove中认为:距离越远的两个单词所占总计数的权重应该越小。所以她它根据两个单词在上下文窗口的距离d,使用一个衰减函数作为计算权重。
2. 引入向量表示,使用共线矩阵的特性建立关系
首先引入几个符号: 就是表示共现矩阵的那一行。 条件概率,表示单词k出现在单词i的语境汇总的概率。 两个条件概率的比率。 作者发现了这样一个规律:
的值 | 单词j,k相关 | 单词j,k不相关 |
---|---|---|
单词i,k相关 | 趋近1 | 很大 |
单词i,k不相关 | 很小 | 趋近1 |
思想: 假设我们已经得到了词向量,如果我们使用词向量通过某种函数计算得到,能够同样得到这样的规律的话,就意味着我们的词向量具备与共现矩阵很好的一致性,也就是说我们的词向量中蕴含了共现矩阵所蕴含的信息,而共现矩阵中所蕴含的信息就是在一个语料中某两个词语相关性的信息。 因此,我们可以构建出词向量与共现矩阵之间的近似关系,使用下面的公式表示:
其中就是我们最终要求的词向量。 至于这个公式怎么来的,网上有很多解释公式推导1,公式推导2。
3. 构建loss function
然后就可以构造他们的损失函数:
这个损失函数就是最简单的mean spuare loss,只不过在前面加了一个权重函数,这个函数的作用是为了根据两个单词共现的数量来做某种约束。具体来讲: 在一个语料中,肯定有很多单词他们共现的数量很多(frequent co-occurrences),我们希望:
- 这些单词的权重要大于那些很少在一起出现的单词(rare co-occurrences),所以这个函数要是非递减函数(non-decreasing);
- 但我们也不希望这个权重过大(overweighted),当到达一定程度之后应该不再增加;
- 如果两个单词没有在一起出现,也就是,那么他们应该不参与到loss function的计算当中去,也就是要满足
作者采用的是如下形式的分段函数:
这个函数的图像如下所示:
4. 训练
采用了AdaGrad的梯度下降算法,对矩阵X中的所有非零元素进行随机采样,学习曲率(learning rate)设为0.05,在vectorsize小于300的情况下迭代了50次,其他大小的vectors上迭代了100次,直至收敛。 因为X是对称的,所以学出来的也应该是对称的,只是由于初始值不同,导致最终数值不一样。因此,为了提高鲁棒性,最终选择两者之和作为最终的词向量。
根据作者做的实验结论得到:向量维度=300,context windows size在6,10之间是,效果最佳。
5.实战指南
我使用的是python傻瓜版本,glove-python,因为我只是训练得到词向量,所以比较简易。
- 安装pip install glove_python
- 准备自己的数据集,分词后用空格分隔(可以全部放在一行,也可以分行来放)
- 然后修改文件名字为‘text8’
- 直接命令行运行demo脚本
./demo.sh
- 得到结果,vectors.txt
[参考:]
pytorch实现
GloVe背后的计算原理
NLP学习(1)---Glove模型---词向量模型