话不多说,直接上干货。
首先介绍相关概念:
词嵌入:把词映射为实数域上向量的技术也叫词嵌入(word embedding)。
词向量的分类表示:
一、共现矩阵
通过统计一个事先指定大小的窗口内的word共现次数,以word周边的共现词的次数做为当前word的vector。具体来说,我们通过从大量的语料文本中构建一个共现矩阵来定义word representation。
例如,有语料如下:
I like deep learning. |
得到共现矩阵X如下:
此时选的窗口大小为3,选择在该窗口内词汇的共现频率作为vector。
矩阵定义词向量的优点:在一定程度上缓解了one-hot向量相似度为0的问题,但依旧没有解决数据系数和维度灾难的问题。
二、SVD(奇异值分解)
既然基于共现矩阵得到的离散词向量存在着高维和稀疏性的问题,一个自然而然的解决思路是对原始词向量进行降维,从而得到一个稠密的连续词向量。
首先,统计一个词语的共生矩阵X。X是一个|V|×|V| 大小的矩阵,Xij表示在所有语料中,词汇表V
中第i个词和第j个词同时出现的词数,|V|为词汇表的大小。对X做矩阵分解(如奇异值分解)得到矩阵正交矩阵U,对U进行归一化得到矩阵,即视为所有词的词向量:
SVD得到了word的稠密(dense)矩阵,该矩阵具有很多良好的性质:语义相近的词在向量空间相近,甚至可以一定程度反映word间的线性关系。
但这样的传统做法有很多问题:
- 由于很多词没有出现,导致矩阵极其稀疏,因此需要对词频做额外处理来达到好的矩阵分解效果;
- 矩阵非常大,维度太高
- 需要手动去掉停用词(如although, a,...),不然这些频繁出现的词也会影响矩阵分解的效果。
奇异值分解可见本专栏的博客。
三、神经网络语言模型(NNLM)
NNLM由Bengio等人提出,他的主要想法就是:
1. 把字典里的每一个单词对应一个词特征向量
2. 把单词序列表示成联合概率函数
3. 自动学习词特征向量和概率函数的参数
在NNLM中,每一个单词为向量空间中的一个点,而且特征的数目要比字典的大小要小,它的概率函数表示为在给定前一个词下,后一个词的条件概率的乘积。
输入:
(1)首先是对整个词汇表建立一个索引,每个单词对应一个索引号,其实就是one-hot编码
(2)one-hot编码建立索引矩阵D,维度为 (n−1)×|V|,即每一行代表一个单词的one hot。
(3)而矩阵C每一行为一个单词的词向量,这样D⋅C就抽取出对应单词的向量了,这就是图中的table look-up in c
(4)找出对应的词向量后,将这些词向量拼接在一起,形成一个 (n−1)m维的列向量x
(5)经过隐含层tanh函数的激活,再经过softmax输出层的输出,这就得到了函数g的输出向量。
输出:
函数g把输入的上下文单词的特征向量(C(wt−n+1),...,C(wt−1))映射为下一个单词wt的条件概率分布函数,当然,这个单词wt在字典V中。
四、Word2Vec
2013年,Google团队发表了word2vec工具。word2vec工具主要包含两个模型:跳字模型(skip-gram)和连续词袋模型(continuous bag of words,简称CBOW),以及两种近似训练法:负采样(negative sampling)和层序softmax(hierarchical softmax)。值得一提的是,word2vec的词向量可以较好地表达不同词之间的相似和类比关系。
在skip-gram模型中,我们用一个词来预测它在文本序列周围的词。
在cbow模型中,我们用周围词来预测核心词。
word2vec详情可参考我的这篇博客
五、Glove
Glove是斯坦福大学Jeffrey Pennington等人提出的,他们认为虽然skip-gram模型在计算近义词方面比较出色,但它们只是在局部上下文窗口训练模型,并且它很少使用语料中的一些统计信息,因此Jeffrey Pennington等人又提出了一个新型模型GloVe。。
首先给一些说明,词-词共现计数矩阵可以表示为X,则Xij为单词j出现在单词i上下文中的次数。Xi=ΣkXik表示任何词出现在单词i上下文中的次数,Pij=P(j|i)=Xij/Xi表示单词j出现在单词i上下文中的比率。
使用一个例子来说明是怎样从共现概率中抽取确定的意思,其实也就是说,和哪个上下文单词在一起的多,那么这个单词与这个上下文单词在一起要比与其他词在一起意义要大。
例如i=ice, j=steam,假设有共现词k,但是k与ice
的联系要比与steam
的联系强,也就是说单词k与ice
出现的概率比与 steam
出现的概率大,比如说k=solid
,那么我们认Pik/Pjk会很大。
相似地,如果单词k与steam的联系比与ice的联系强,例如k=gas,那么Pik/Pjk的比率会很小,对于其他的单词k如water, fashion与ice,steam联系都强或都不强的话,则Pik/Pjk的比率会接近1。
这个比率就能区别相关词(solid, gas
)和不相关词(water, fashion
),并且也能区别这两个相关的词(solid, gas
)。那么得到的向量可能为ice-steam=solid-gas
,这与word2vec相似。
word2vec和glove的区别:
Omer Levy等人对基于计数的方法和基于embedding的方法做了对比,发现它们之间并没有非常大的差距,在不同的场景各个模型发挥不同的作用,它们之间并没有谁一定优于谁,相比于算法而言,增加语料量,进行预处理以及超参数的调整显得非常重要。特别指出,基于negtive sampling的skip-gram模型可以作为一个基准,尽管对不同的任务它可能不是最好的,但是它训练快,占用内存和磁盘空间少。
六、ELMo-动态词向量
艾伦研究所开发,并于6月初在NAACL 2018年发布ELMo(深度语境化的单词表示)。ELMo(Embeddings from Language Models) ,被称为时下最好的通用词和句子嵌入方法,来自于语言模型的词向量表示,也是利用了深度上下文单词表征,该模型的优势:
(1)能够处理单词用法中的复杂特性(比如句法和语义)
(2)这些用法在不同的语言上下文中如何变化(比如为词的多义性建模)
ELMo与word2vec、glove最大的不同:即词向量不是一成不变的,而是根据上下文而随时变化,这与word2vec或者glove具有很大的区别。
举个例子:针对某一词多义的词汇 w="苹果" |
ELMo是双向语言模型bilm的多层表示的组合,基于大量文本,ELMo模型是从深层的双向语言模型(deep bidirectional language model)中的内部状态(internal state)学习而来的,而这些词向量很容易加入到QA、文本对齐、文本分类等模型中,后面会展示一下ELMo词向量在各个任务上的表现。
它首先在大文本语料库上预训练了一个深度双向语言模型(bilm),然后把根据它的内部状态学到的函数作为词向量。实验表明,这些学到的词表征可以轻易地加入到现有的模型中,并在回答问题、文本蕴含、情感分析等 6 个不同的有难度的 NLP 问题中大幅提高最佳表现。实验表明显露出预训练模型的深度内部状态这一做法非常重要,这使得后续的模型可以混合不同种类的半监督信号。
使用ELMo获得词向量替换Glove的词向量作为多项特定NLP模型的输入,在ELMO实验论文中表明具有一定的效果提升:
ps:
elmo很厉害,但并不是说在中文语料的表现上比word2vec好很多。据哈工大的研究表明,从句发任务的角度出发,在OOV比例高的数据中ELMO效果好。哈工大分析了OOV、traning data size、morphological richness等因素。在多国语法任务中,OOV rate与ELMo带来的提升的相关性最高。(当然,这些因素之间实际上不是正交的,traning data size比较小的往往OOV rate也高,morphology rich的数据OOV往往更多)。
回到中文的问题,ELMo能否比word2vec好以及好多少,和实际任务关系可能很大。
如果是训练数据很少或者接近zero-shot,one-shot这种settings,ELMo很可能表现得更好。如果训练数据很好(比如其他答案中提到的dureader数据),ELMo可能没什么效果。
除此之外,中文是形态不丰富的语言,这点可能会影响ELMo的发挥。
详情可见链接。