原文链接: http://chenhao.space/post/89252767.html
word2vec
Skip-Gram

跳字模型其实就是利用中心词预测上下文词这种方法来训练词向量。我们会得到跳字模型其实就是利用中心词预测上下文词这种方法来训练词向量。我们会得到两个向量,第一个是中心词向量,另一个是上下文词的向量。而我们是用跳字模型得到的中心词向量作为词的表征向量。

其中矩阵 W 和 W′ 就是我们训练得到的两个权重矩阵,d 表示的是词表征向量的维度,V 表示的是词的个数。W 就是所有中心词向量的合成的矩阵,W′ 是所有上下文词向量合成的矩阵。
下图可能看起来更直观一点:

计算:
假设这个词在词典中索引为i,当它为中心词时向量表示为vi,而为背景词时向量表示为ui(背景词=上下文词)。设中心词wc在词典中索引为c,背景词wo在词典中索引为o,给定中心词生成背景词的条件概率可以通过对向量内积做softmax运算而得到:
P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc),
V是词典索引集合,假设给定一个长度为T的文本序列,设时间步t的词为w(t)。假设给定中心词的情况下背景词的生成相互独立,当背景窗口大小为m时,跳字模型的似然函数即给定任一中心词生成所有背景词的概率:
t=1∏T−m≤j≤m, j=0∏P(w(t+j)∣w(t)),
训练中我们通过最大化似然函数来学习模型参数,即最大似然估计。这等价于最小化以下损失函数:
−T1t=1∑T−m≤j≤m, j=0∑logP(w(t+j)∣w(t)).
将第一个条件概率公式取log,得到:
logP(wo∣wc)=uo⊤vc−log(i∈V∑exp(ui⊤vc))
通过微分,我们可以得到上式中 vc 的梯度:
∂vc∂logP(wo∣wc)=uo−∑i∈Vexp(ui⊤vc)∑j∈Vexp(uj⊤vc)uj=uo−j∈V∑(∑i∈Vexp(ui⊤vc)exp(uj⊤vc))uj=uo−j∈V∑P(wj∣wc)uj.
再根据 vc=vc−∂vc∂L 来迭代它。
CBOW
连续跳字模型是由上下文词(或背景词)生成中心词。
因为连续词袋模型的背景词有多个,我们将这些背景词向量取平均,再与 W 相乘,得到一个Hidden layer,再与 W′ 相乘,这里的 W′ 就是我们要训练得到的中心词向量集合成的矩阵。

给定一个长度为T的文本序列,设时间步t的词为w(t),背景窗口大小为m。连续词袋模型的似然函数是由背景词生成任一中心词的概率:
t=1∏TP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m)).
连续词袋模型的最大似然估计等价于最小化损失函数:
−t=1∑TlogP(w(t)∣w(t−m),…,w(t−1),w(t+1),…,w(t+m)).
而给定背景词生成中心词的条件概率为:
P(wc∣wo1,…,wo2m)=∑i∈Vexp(2m1ui⊤(vo1+…+vo2m))exp(2m1uc⊤(vo1+…+vo2m)).
记 Wo={wo1,…,wo2m},且 vˉo=(vo1+…+vo2m)/(2m) ,则:
P(wc∣Wo)=∑i∈Vexp(ui⊤vˉo)exp(uc⊤vˉo).
求导:
∂voi∂logP(wc∣Wo)=2m1⎝⎛uc−j∈V∑∑i∈Vexp(ui⊤vˉo)exp(uj⊤vˉo)uj⎠⎞=2m1⎝⎛uc−j∈V∑P(wj∣Wo)uj⎠⎞.
近似训练
由于条件概率使用了softmax运算,每一步的梯度计算都包含词典大小数目的项的累加。对于含几十万或上百万词的较大词典,每次的梯度计算开销可能过大。如:
P(wo∣wc)=∑i∈Vexp(ui⊤vc)exp(uo⊤vc)
它的分母引入了 ∑i∈V ,是因为skip-gram模型考虑了每个背景词可能是字典中任意一个词(skip-gram由中心词预测背景词)。这样分母之和为1,但也造成了庞大的计算开销。
为了降低该计算复杂度,引入两种近似训练方法,即负采样(negative sampling)或层序softmax(hierarchical softmax)。
Hierarchical Softmax
Hierarchical softmax 使用一个二叉树来表示词表中的所有词。树中的每个叶结点都是词典中的一个单词,而且只有一条路径从根结点到叶结点。

假设 L(w) 为从二叉树的根结点到词 w 的叶结点的路径(包括根结点和叶结点)上的结点数。设 n(w,j) 为该路径上第 j 个结点,并设该结点的背景词向量为 un(w,j)。如上图,L(w3)=4。层序softmax将跳字模型中的条件概率近似表示为:
P(wo∣wc)=j=1∏L(wo)−1σ([[n(wo,j+1)=leftChild(n(wo,j))]]⋅un(wo,j)⊤vc),
其中的 σ 是 sigmoid 函数,leftChild(n) 是结点 n 的左子结点:如果判断 x 为真,[[x]]=1;反之 [[x]]=−1。
例入计算给定词 wc 生成词 w3 的条件概率:
P(w3∣wc)=σ(un(w3,1)⊤vc)⋅σ(−un(w3,2)⊤vc)⋅σ(un(w3,3)⊤vc).
由于σ(x)+σ(−x)=1,给定中心词 wc 生成词典 V 中任一词的条件概率之和为1这一条件也将满足:
w∈V∑P(w∣wc)=1
这种方法最大的优势是计算概率的时间复杂度仅仅是 O(log2∣V∣).
Negative Sampling
Negative Sampling 每次让一个训练样本仅仅更新一小部分的权重参数,从而降低梯度下降过程中的计算量。
以skip-gram为例,如一个句子“The quick brown fox jumps over the lazy dog”。如果 vocabulary 大小为1万时, 当输入样本 ( “fox”, “quick”) 到神经网络时, “ fox” 经过 one-hot 编码,在输出层我们期望对应 “quick” 单词的那个神经元结点输出 1,其余 9999 个都应该输出 0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们为 negative word。Negative Sampling 的想法是将随机选择一小部分的 negative words,比如选 10个 negative words 来更新对应的权重参数。
fastText
FastText 是一个用于高效学习单词表示和句子分类的库。
论文:Enriching Word Vectors with Subword Information
来源:ACL 2016
Introduction
这篇论文提出了用 character n-grams 的向量之和来代替简单的词向量的方法,以解决简单 word2vec 无法处理同一词的不同形态(the morphology of words)的问题。例如,“dog”和“dogs”分别用两个不同的向量表示,而模型中并未直接表达这两个向量之间的关系。
而子词嵌入的思想可以考虑到有些词形态间的联系。例如,我们可以从“dog”“dogs”和“dogcatcher”的字面上推测它们的关系。这些词都有同一个词根“dog”,但使用不同的后缀来改变词的含义。而且,这个关联可以推广至其他词汇。例如,“dog”和“dogs”的关系如同“cat”和“cats”的关系。
Model
本篇论文的模型是基于Skip-gram进行改动的。

以单词“where”,n-gram 以n=3为例。“where”被charater n-gram表示为:
<wh,whe,her,ere,re>
以及特殊子词 “<where>” ,把它们相加得到词“where”的词表征。
该模型就相当于把skip-gram的中心词的词表征做了一些变换。训练过程与skip-gram一致。
Conclusion
- fastText提出了子词嵌入方法。它在word2vec中的跳字模型的基础上,将中心词向量表示成单词的子词向量之和。
- 子词嵌入利用构词上的规律,通常可以提升生僻词表示的质量。
论文:Bag of Tricks for Efficient Text Classification
来源:ACL 2016
Introduction
虽然神经网络模型在文本分类中取得了很好的表现,但是它们在训练和测试时的速度相对较慢,限制了它们在非常大的数据集上的使用。所以作者提出了fastText,它适合大型数据 + 高效的训练速度,并进行了两个任务的实验,标签预测和情感分析。
实验结果表明fastText的准确性方面与深度学习分类器相当,在训练和评估方面快了几个数量级。
Model architecture
该模型是基于CBOW进行改动的。

Input layer:输入是多个单词及其n-gram特征,这些特征用来表示单个文本。(因为词袋模型不考虑词序的问题,若将词序信息添加进去又会造成过高的计算代价。文章为了把word order引入,使用了N-gram feature, 并使用哈希算法高效的存储n-gram信息。)
Hidden layer:由输入层求和并平均,乘以权重矩阵A得到的。
Output layer:linear + softmax,输出分类类别。
我们要最大化下面对数似然函数:
n=1∑Nynlog(f(BAxn))
也就是要最小化负的对数似然函数(loss function):
−N1n=1∑Nynlog(f(BAxn))
其中,A 和 B 均是权重矩阵,xn 是文档n归一化后的n-gram feature,yn 是label,f 是softmax函数(当分类的类别数较多时,会使用hierarchical softmax加速)。
|
Word2Vec |
fastText |
| 输入 |
one-hot形式的单词的向量 |
embedding过的单词的词向量和n-gram向量 |
| 输出 |
对应的是每一个term,计算某term概率最大 |
对应的是分类的标签 |
Word2Vec用CBOW模型训练词向量得到word embedding,而fastText是用已经训练好的单词的word embedding和n-gram向量来进行文本分类。所以它的模型简单,训练速度非常快,适合用于大数据集。
Experiments

h=10 表示10个hidden units,也就是使用了10维的特征。
FastText最大的特点是模型简单,只有一层的隐层以及输出层,因此训练速度非常快。
Others
Hash
由于n-gram的量远比词的数量大的多,完全存下所有的n-gram是不太现实的。Fasttext采用了Hash桶的方式,把所有的n-gram都哈希到buckets个桶中,哈希到同一个桶的所有n-gram共享一个embedding vector。如下图所示:

用哈希的方式既能保证查找时O(1)的效率,又可能把内存消耗控制在O(bucket×dim)范围内。不过这种方法潜在的问题是存在哈希冲突,不同的n-gram可能会共享同一个embedding。如果桶大小取的足够大,这种影响会很小。
参考资料
- 动手深度学习-李沐著
- Distributed Representations of Words and Phrases and their Compositionality(2013)
- Bag of Tricks for Efficient Text Classification(2016)
- Enriching Word Vectors with Subword Information
- http://web.stanford.edu/class/cs224n/
- https://www.paperweekly.site/papers/notes/132
- http://albertxiebnu.github.io/fasttext/
- [https://github.com/NLP-LOVE/ML-NLP/tree/master/NLP/16.2%20fastText](https://github.com/NLP-LOVE/ML-NLP/tree/master/NLP/16.2 fastText)
- [[https://github.com/llhthinker/NLP-Papers/blob/master/distributed%20representations/2017-11/Enriching%20Word%20Vectors%20with%20Subword%20Information/note.md](https://github.com/llhthinker/NLP-Papers/blob/master/distributed representations/2017-11/Enriching Word Vectors with Subword Information/note.md)]([https://github.com/llhthinker/NLP-Papers/blob/master/distributed%20representations/2017-11/Enriching%20Word%20Vectors%20with%20Subword%20Information/note.md](https://github.com/llhthinker/NLP-Papers/blob/master/distributed representations/2017-11/Enriching Word Vectors with Subword Information/note.md))