word2vec 的计算
在前一节中,介绍了 word2vec 的 Skip-grams 模式,即通过中心词预测上下文词的工作方式,接下来使用该方式计算词向量,具体步骤包括
- 初始化词向量(普遍使用 one-hot 编码)
- 计算每个词的条件概率
$$P(o|c)=\frac{\exp(u_o^Tv_c)}{\sum_{w\in V}\exp(u_w^Tv_c)}$$
- 通过迭代优化的方法(梯度下降、随机梯度下降),改变词向量的值,最小化损失函数
$$J(\theta)=-\frac{1}{T}\log L(\theta)=-\frac{1}{T}\prod^T_{t=1}\prod_{\substack{-m\leq j\leq m\\j\neq0}}P(w_{t+j}|w_t;\theta)$$最终得到基于分布式语义的词向量结果。
负采样
计算 \(\sum_{w\in V}\exp(u_w^Tv_c)\) 具有巨大的开销,负采样是一种优化词向量计算效率的一种方法,负采样的思路是将由中心词预测多个上下文词的多分类问题转化为二分类问题,即判断目标词是否为中心词。
首先定义 \(D\) 为词对 \((c,o)\) 的集合(中心词 center,上下文 outside),那么对于任意词对 \((c,w)\),它们之间互为上下文的概率为
其中 \(\sigma(x)=\frac{1}{1+e^{-x}}\),又称为 Sigmoid 函数,根据 Sigmoid 函数的性质,当 \(c\) 与 \(w\) 相似程度大时,二者为上下文概率高,当相似程度低时,互为上下文概率低,同样是分布式语义的思想。
全部正样本的似然函数为
全部负样本的似然函数为
优化目标是使正样本尽可能多,负样本尽可能少,所以优化目标可以写作
取对数并整理后可以得到
也就是说负采样需要从文本中抽取若干个词组成负样本集 \(\mathrm{NEG}(w)\),并迭代最小化损失函数得到词向量,这也是「负采样」一名的含义。通常将文本中各词的频率 \(f(w)\) 缩放为 \(f(w)^{3/4}\) ,以此作为概率从文本中抽取词组成负样本集,避免忽略低频词。
共现矩阵
与 word2vec 利用概率预测得到词向量不同,共现矩阵是一种通过直接计数得到词向量的方法。设定一个大小为 \(m\) 的窗口,让该窗口经过语料中的所有中心词,并统计所有中心词所属窗口中不同上下文词的数量,将结果列为表格,就是一个 \(|W|\times |W|\) 的矩阵,称为共现矩阵, \(|W|\) 为语料中的词汇数量。在共现矩阵中,元素 \(x_{ij}\) 就表示词 \(w_j\) 作为中心词 \(w_i\) 上下文词的数量。
I like deep learning.
I like NLP.
I enjoy flying.
例如以上三句话构成的语料,设定窗口大小为 1,可以得到以下共现矩阵:
I | like | enjoy | deep | learning | NLP | flying | . | |
---|---|---|---|---|---|---|---|---|
I | 0 | 2 | 1 | 0 | 0 | 0 | 0 | 0 |
like | 2 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
enjoy | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
deep | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 |
learning | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
NLP | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
flying | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
. | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 |
共现矩阵是一个对称矩阵,从共现矩阵中也可以得到词向量,如 \(w^\mathrm{T}(\mathrm{I})=(0\ 2\ 1\ 0\ 0\ 0\ 0\ 0)\)。共现矩阵得到的向量普遍较为稀疏,通过奇异值分解可以将共现矩阵转化为更为稠密的特征矩阵,从而得到稠密的词向量。
共现概率
共现矩阵通过计数获取中心词与上下文词的关系,因此词频对共现矩阵有着很大影响,例如以下这个例子:
\(x=\mathrm{solid}\) | \(x=\mathrm{gas}\) | \(x=\mathrm{water}\) | \(x=\mathrm{random}\) | |
---|---|---|---|---|
\(P(x\vert\mathrm{ice})\) | large | small | large | small |
\(P(x\vert\mathrm{steam})\) | small | large | large | small |
\(\frac{P(x\vert\mathrm{ice})}{P(x\vert\mathrm{steam})}\) | large | small | ~1 | ~1 |
依据直觉判断,「冰(ice)」与「固体(solid)」存在着很强的相关性,「蒸汽(steam)」与「气体(gas)」存在着很强的相关性,基于计数得到的 \(P(x|\mathrm{ice})\) 与 \(P(x|\mathrm{steam})\) 确实能反映这一关系。但在遇到高频词与低频词时就有了麻烦,表中用的例子是 「water」 和 「random」,我们不妨考虑更极端的情况,考虑高频词为冠词 「the」,低频词为很难见到的「thou」,结果会怎样呢?\(P(x|\mathrm{ice})\) 与 \(P(x|\mathrm{steam})\) 对于高频词都有着较大值,对低频词都有着较小值,无法判断相关性了。
为了避免高频词与低频词的影响,更加真实地反映词义,通常会使用共现概率(co-occurrence probabilities)进行词义分析,即表中的 \(\frac{P(x\vert\mathrm{ice})}{P(x\vert\mathrm{steam})}\) ,共现概率通过除法消除了共有高频词与低频词的影响,只有与中心词有着较强语义关联的词才会具有较大值。
GloVe
基于计数的共现矩阵与基于概率预测的 word2vec 各有优缺点,而 GloVe 则结合了二者的优点。GloVe 全称为 Global Vectors,GloVe 得到的词向量既能像基于计数的方法一样全面利用信息,又能像基于概率预测的方法一样表示比相关性更多更复杂的关系。
GloVe 首先通过对共现概率建立模型,具有如下形式:
其中 \(w_i\) 与 \(w_j\) 是比较的目标词,例如上表中的「ice」与「steam」,\(\tilde{w}\) 为上下文词,即上表中的「solid」与「gas」等,\(P_{ij}=P(j|i)\) 表示由计数得到的共现概率。
接着参考 word2vec 中相似向量具有相同语义的思想,我们会希望 GloVe 得到的相似词向量具有强相关性,也就是较大的 \(P_{ij}\),向量的数量积是衡量向量相似性的自然方法,那么模型的形式可以改为
然后要让模型 \(F\) 中的左侧的向量运算能够表示右侧概率的比值,GloVe 的假设是使用向量的差,也就是
最后求解该模型,在保证对称性等要求下得到 GloVe 模型为
具体推导过程可以参考CS224N笔记(二):GloVe。
词向量中的多重语义
在自然语言中,一个词具有多重的语义,由于语境不同而具有不同的意思,例如汉语中的多音字「省」,那么词向量该如何处理这种状况呢?
要明确的是,词向量是基于语料中的分布式语义得到的,虽然这种分布与语境还存在一定差异,但二者具有很大的相似性。正如当我们看到文章中的「省」字时不会像词典一样列举出所有含义,而是根据上下文或是最常见的义项做出判断,词向量也是如此。
词向量可以看作多个语义的线性组合,因此词向量也具有多重语义,可以表示为
其中权值 \(\alpha\) 由语料中词汇的频率 \(f\) 决定,可以表示为