Word2vec
one-hot表示
主要问题
- 无法准确表达不同词之间的相似度,没有任何语义信息
以下内容主要摘抄自
- 来斯惟的博士论文基于神经网络的词和文档语义向量表示方法研究
- CS224n的notes
- Yoav Goldberg的word2vec Explained: Deriving Mikolov et al.’s
Negative-Sampling Word-Embedding Method
分布假说(distributional hypothesis)
Harris 在 1954 年提出的分布假说(distributional hypothesis):上下文相似的词,其语义也相似 。Firth 在 1957 年对分布假说进行了进一步阐述和明确:词的语义由其上下文决定(a word is characterized by the company it keeps。到目前为止,基于分布假说的词表示方法,根据建模的不同,主要可以分为三类:基于矩阵的分布表示、基于聚类的分布表示和基于神经网络的分布表示。从广义上看,所有基于分布假说得到的表示均可称为分布表示(distributional representation),如上述的三种。而狭义的分布表示通常指基于矩阵的分布表示 。
基于矩阵的分布表示
这类方法构建一个“词-上下文”矩阵,从矩阵中获取词的表示。在“词-上下文”矩阵中,每行对应一个词,每列表示一种不同的上下文,矩阵中的每个元素对应相关词和上下文的共现次数。在这种表示下,矩阵中的一行,就成为了对应词的表示,这种表示描述了该词的上下文的分布。由于分布假说认为上下文相似的词,其语义也相似,因此在这种表示下,两个词的语义相似度可以直接转化为两个向量的空间距离。这类方法具体可以分为三个步骤:
- 选取上下文。最常见的有三种方法:第一种,将词所在的文档作为上下文,形成“词-文档”矩阵 ;第二种,将词附近上下文中的各个词作为上下文,形成“词-词”矩阵;第三种,将词附近上下文各词组成的 n 元词组(n-gram)作为上下文。在这三种方法中,“词-文档”矩阵非常稀疏,而“词-词”矩阵相对较为稠密,效果一般好于前者。“词-n 元词组”相对“词-词”矩阵保留了词序信息,建模更精确,但由于比前者更稀疏,实际效果不一定能超越前者。
- 确定矩阵中各元素的值。“词-上下文”共现矩阵根据其定义,里面各元素的值应为词与对应的上下文的共现次数。然而直接使用原始共现次数作为矩阵的值在大多数情况下效果并不好,因此研究人员提出了多种加权和平滑方法,最常用的有 tf-idf、PMI 和直接取 log。
- 矩阵分解(可选)。在原始的“词-上下文”矩阵中,每个词表示为一个非常高维(维度是不同上下文的总个数)且非常稀疏的向量,使用降维技术可以将这一高维稀疏向量压缩成低维稠密向量。降维技术可以减少噪声带来的影响,但也可能损失一部分信息。最常用的分解技术包括奇异值分解(SVD)、非负矩阵分解(NMF)、典型关联分析(Canonical Correlation Analysis,CCA)、Hellinger PCA(HPCA)。基于矩阵的分布表示在这些步骤的基础上,衍生出了若干不同方法,如经典的 LSA 就是使用“词-文档”矩阵,tf-idf 作为矩阵元素的值,并使用 SVD分解,得到词的低维向量表示。在这类方法中,最新的为 GloVe 模型 。
Global Vector 模型(GloVe)
总体上看,GloVe 模型是一种对“词-词”矩阵进行分解从而得到词表示的方法。矩阵第 \(i\) 行第 \(j\) 列的值为词 \(v_i\) 与词 \(v_j\) 在语料中的共现次数 \(x_{ij}\) 的对数。在矩阵分解步骤,GloVe 模型借鉴了推荐系统中基于隐因子分解(Latent Factor Model)的方法,在计算重构误差时,只考虑共现次数非零的矩阵元素,同时对矩阵中的行和列加入了偏移项。具体为最小化下式:
其中 \(\boldsymbol{p}_{i}\) 为词 \(v_i\) 作为目标词时的词向量,\(\boldsymbol{q}_{j}\) 为词 \(v_j\) 作为上下文时的词向量,\(b^{(1)}\)、\(b^{(2)}\) 为针对词表中各词的偏移向量,\(f(x)\) 是一个加权函数,对低频的共现词对进行衰减,减少低频噪声带来的误差,定义为
基于神经网络的分布表示
基于神经网络的分布表示一般称为词向量、词嵌入(word embedding)或分布式表示(distributed representation)。
几个重要模型
- 神经网络语言模型(Neural Network Language Model ,NNLM)
- log双线性语言模型(Log-Bilinear Language Model,LBL)
- 循环神经网络语言模型(Recurrent Neural Network based Language Model,RNNLM)
- word2vec
下面主要介绍word2vec,这也是现在最流行的表示方法之一。
word2vec
word2vec不是一个单一模型,实际是两个表示模型 CBOW(Continuous Bagof-Words), Skip-Gram和两个优化训练的方法Negative-Sampling和Hierarchical Softmax的方法组成的
skip-gram
跳字模型基于某个词来生成它在文本序列周围的词。且假设给定中心词的情况下,背景词的生成是相互独立的,算法如下:
表示说明:
词库大小设为\(|V|\)
\(w_i\):词库中的第\(i\)个单词
\(\mathcal{V} \in \mathbb{R}^{n \times|V|}\):输入矩阵
\(v_{i}\):输入矩阵的第\(i\)列,实际就是\(w_i\)的向量表示。
\(\mathcal{U} \in \mathbb{R}^{[V| \times n}\):输出矩阵
\(u_i\):输出矩阵的第\(i\)行,\(w_i\)的输出向量表示
步骤:
- 生成输入中心词的one-hot表示 \(x \in \mathbb{R}^{|V|}\)
- 词嵌入\(v_{c}=\mathcal{V} x \in \mathbb{R}^n\)
- \(z=\mathcal{U} v_{c}\)
- \(\hat{y}=\operatorname{softmax}(z)\)
- \(\hat{y}_{c-m}, \ldots, \hat{y}_{c-1}, \hat{y}_{c+1}, \dots, \hat{y}_{c+m}\)作比较
目标函数:
另一种表达:
\(H\left(\hat{y}, y_{c-m+j}\right)\)表示交叉熵
利用了独立性假设,然后梯度下降更新参数即可。
CBOW
连续词袋模型与跳字模型类似。与跳字模型最大的不同在于,连续词袋模型假设基于某中心词在文本序列前后的背景词来生成该中心词。因为连续词袋模型的背景词有多个,我们将这些背景词向量取平均,然后使用和跳字模型一样的方法来计算条件概率。
表示说明:
词库大小设为\(|V|\)
\(w_i\):词库中的第\(i\)个单词
\(\mathcal{V} \in \mathbb{R}^{n \times|V|}\):输入矩阵
\(v_{i}\):输入矩阵的第\(i\)列,实际就是\(w_i\)的向量表示。
\(\mathcal{U} \in \mathbb{R}^{[V| \times n}\):输出矩阵
\(u_i\):输出矩阵的第\(i\)行,\(w_i\)的输出向量表示
步骤:
- 输入:根据窗口大小生成one-hot的上下文向量 \(\left(x^{(c-m)}, \ldots, x^{(c-1)}, x^{(c+1)}, \ldots, x^{(c+m)} \in \mathbb{R}^{|V|}\right)\)
- 得到上下文的embedded word vectors\((v_{c-m} = \mathcal{V} x^{(c-m)}, v_{c-m+1}=\mathcal{V} x^{(c-m+1)}, \ldots, v_{c+m}=\mathcal{V} x^{(c+m)} \in \mathbb{R}^{n} )\)
- 求平均\(\hat{v}=\frac{v_{c-m}+v_{c-m+1}+\ldots+v_{c+m}}{2 m} \in \mathbb{R}^{n}\)
- 生成score vector \(z=\mathcal{U} \hat{v} \in \mathbb{R}^{|V|}\)
- softmax,\(\hat{y}=\operatorname{softmax}(z) \in \mathbb{R}^{|V|}\),实际就是给定中心词,产生上下文的概率。与真实作比较,定义损失函数,一般是交叉熵。groundtruth是样本对应的那个词的one-hot表示。
对于每个单词,我们想要得到的是两个向量,\(v\): (input vector) when the word is in
the context,\(u\): (output vector) when the word is in the center,输入和输出矩阵是我们想要学习的参数。一个问题是我们究竟用哪一个作为embedding呢?实际上输入和输出矩阵都可以作为embedding,但是原文中使用的是输入矩阵作为embedding。
如何计算:
然后用梯度下降的方法更新参数即可。
Negative Sampling
基于skip-gram,上面推导的两个目标函数最大的问题是连加那里,要对整个词库进行计算,对于大词库,这是很大运算量,所以想办法近似求解。负采样(negative sampling)解决了这个问题,它是用来提高训练速度并且改善所得到词向量的质量的一种方法。不同于原本每个训练样本更新所有的权重,负采样每次让一个训练样本仅仅更新一小部分的权重,这样就会降低梯度下降过程中的计算量。负采样修改了原来的目标函数。给定中心词 \(c\) 的一个背景窗口,我们把背景词 \(w\) 出现在该背景窗口看作一个事件
考虑\((w,c)\)是否来自训练数据,来自训练数据的概率可以表示为:
转变优化目标为,当中新词和上下文来自训练数据时最大化其概率,不来自的时候,最大化不来自的概率。然后简单的用极大似然估计:
极大似然也就等价于极小以下函数:
对于skip-gram得到新的目标函数
如何选择negative words
使用“一元模型分布(unigram distribution)”来选择“negative words”。
\(P\left(w_{i}\right)=\frac{f\left(w_{i}\right)^{3 / 4}}{\sum_{j=0}^{n}\left(f\left(w_{j}\right)^{3 / 4}\right)}\)
每个单词被赋予一个权重,即\(f(w_i)\), 它代表着单词出现的频次。
关于负采样的详细解释,可以参考Yoav Goldberg的那篇paper。
Hierarchical Softmax
层序softmax是另一种近似训练法。它使用了二叉树这一数据结构,树的每个叶结点代表词典 \(\mathcal{V}\) 中的每个词。
假设 \(L(w)\) 为从二叉树的根结点到词 \(w\) 的叶结点的路径(包括根结点和叶结点)上的结点数。设 \(n(w,j)\) 为该路径上第 $j $个结点,并设该结点的背景词向量为 \(\boldsymbol{u}_{n(w,j)}\)。如图\(L(w_3)=4\) 。层序softmax将跳字模型中的条件概率近似表示为$$P(w_o \mid w_c) = \prod_{j=1}^{L(w_o)-1} \sigma\left( [![ n(w_o, j+1) = \text{leftChild}(n(w_o,j)) ]!] \cdot \boldsymbol{u}_{n(w_o,j)}^\top \boldsymbol{v}_c\right)$$
其中\(\text{leftChild}(n)\)是是结点 \(n\) 的左子结点,如果判断 \(x\) 为真, \([\![x]\!] = 1\),反之为-1。例子:给定词 \(w_c\) 生成词 \(w_3\) 的条件概率
时间复杂度降低至\(\mathcal{O}(\text{log}_2|\mathcal{V}|)\)