2018 年对于自然语言处理 (Natural Language Processing, NPL) 是极有意义的一年, 这一年出现了许多新的研究方向和尖端成果. 在学术界和工业界, 由于带有上下文的嵌入模型对内存和硬件的要求极高, 预先训练词嵌入的使用仍然十分普遍.
- SGNS and Matrix Factorization
- You shall know a Word by the company it keeps. (Firth, 1957)
正如 Firth 所言, 词义的确定需要结合它与其它词语之间的搭配关系, 他所说的 "company" 指的就是与某一词语同现的搭配词语. 构建预先训练词嵌入的优势在于, 其向量表示能够反映通用语言信息, 这些信息对后续任务的开展有很大的帮助. 对于 NLP 而言, 通过创建单词的词嵌入向量, 能够预测可能会出现在该单词周围的单词.
Skip-Gram with Negative Sampling (SGNS)
SGNS 作为一种神经网络模型受到了广泛的关注, 其目的是预测给定当前单词的所有上下文单词. 在下图中, 我们将通过单词 "a", 对 "am","I","neural","network" 等单词进行预测. 词汇量的大小及单词的顺序决定了, 对一个单词, 我们都会产生 million-dimensional 预测向量, 并且需要在整个辞典上计算全部词向量和当前中心词的点积, 这个计算量太大了.
SGNS 的提出者引入了 "负采样(negative sampling)" 来解决这一问题. 其思想就是, 做一个负样本, 可以理解成随机语料. 于是每次训练的时候, 我们就有一个正样本和若干个负样本, 我们让正样本的预测概率尽可能大, 而让负样本预测概率尽可能小, 通过负样本的引入, 将本来建立在整个辞典上的一个 | V | 分类问题, 转换成一个建模在正负样本上的一个二分类问题.
SGNS 的基本过程大致如上图所示, 但当对输出层使用 softmax 函数时, 需要用单词的上下文嵌入 (context embedding) 矩阵 C 乘以输入单词的词嵌入矩阵 W, 该图在这一点上未能清楚描述.
对输出层采用 softmax 函数, 其计算量过大. 负采样 (negative sampling) 的引入能够有效缓解这个问题. 不同于原来每个训练样本更新所有的权重, 负采样每次让一个训练样本仅仅更新一部分的权重, 降低了梯度下降过程中的计算量.
SGNS 其实是一种隐式的矩阵分解
接下来我们将提出一个不同的概念框架来理解 Word2vec, 在深入讨论细节之前, 让我们先形式化一些符号:
Sigma (σ) : 常用的逻辑回归函数
输入单词的词嵌入矩阵 W, 其它上下文单词的词嵌入矩阵 C. 值得注意的是, Word2vec 和 GloVe 一样, 需要单独的单词和上下文嵌入, 即使它们对应相同的词汇表. 这与逻辑回归中将特征向量 (单词) 与学习的权重向量 (上下文) 分离是同一个道理.
下面公式中的求和符号表明, 通过噪声分布 U 近似抽取 k 个负样本.
SGNS 的目标函数如下所示:
损失函数需要帮我们完成以下任务:(1)最大化矩阵 W 与 C 的点积;(2)最小化矩阵 W 和随机采样 k 的点积.
但是目标函数并未包含上下文窗口, 其大小是一个超参数. 下图可以更好的代表 SGNS:
从图中可以看出, SGNS 并未做任何预测. 这个模型和上面的损失函数准确地描述了随机梯度下降过程中采样的每一步嵌入情况. 通俗来讲, 每次模型读取一个单词并查看它周围的上下文时, 我们都能确切地捕捉它的学习过程. 然而它看上去更像是一个自然语言处理的工具, 而不是一个基于神经网络的学习算法.
Levy & Goldberg: Local Prediction is Global Approximation
Levy 和 Goldberg 从理论上证明了 Word2Vec 其实近似等价于矩阵分解(Matrix Factorization), 甚至能够说 SGNS 就是一种隐式的矩阵分解, 类似于 GloVe 和 singular value decomposition.
PMI 矩阵的计算如下所示:
k 是一个超参数, 表示负采样的数量(默认值为 15)
点间互信息 (Pointwise Mutual Information,PMI) 是 NLP 中用得很多的信息度量指标, 主要用于计算词语间的语义相似度, 基本思想是统计两个词语在文本中同时出现的概率, 如果概率越大, 其相关性就越紧密, 关联度越高. 例如,"costa" 和 "rica" 之间就拥有较高的 PMI 值, 因为你看见其中一个单词的时候, 会有很大概率想起另一个单词. PMI 的定义如下所示, 值得注意的是, 如果语料库中从未出现单词 - 上下文对, 那么他们之间的 P(i,j)=0, 其 PMI 值为 log(0), 或者负无穷.
Levy 和 Goldberg 表示, Word2vec 就是隐式的矩阵分解. SGNS 能够将单词和其对应的上下文嵌入到一起, 这样计算得到的点积可以表示它们同时出现的可能性.
只要做到以下几点, 我们就能用矩阵分解算法来实现 SGNS:
1, 根据语料库, 预先计算正确的 PMI 矩阵
2, 找到对应的损失函数
在发现 SGNS 其实就是隐式的矩阵分解后, Levy 和 Goldberg 尝试利用显式矩阵分解表示 SGNS, 如下:
1, 由于 PMI 矩阵是个稠密矩阵, 还会有很多不好处理的缺失值, 而且把缺失值写成 0 也会有问题, 所以分解 Positive PMI 会更合理, 也就是把所有非正值都变成 0:PPMI(x) = max(0, PMI(x))
2, 直接用 SVD 分解, SVD 在复原 PMI 或类似矩阵方面效果非常好, 而且不用调优任何参数.
但该方法并不能很好的代替 SGNS. 原因在与 (1) 没有使用 shifted PMI 矩阵;(2)没有找到正确的损失函数.
来源: https://yq.aliyun.com/articles/694999