c5w2_自然语言处理与词嵌入
自然语言处理与词嵌入
词嵌入
one-hot向量表示了每个词在词汇表中的位置,但是每个one-hot向量的内积为0,不能表示出每个词之间的相互关系。
I want a glass of orange juice. I want a glass of apple __.
例如,对于上述的这样一句话,通过学习算法可能知道在orange后面填入juice是一个不错的选择。 但是算法可能并不知道apple是orange的平替。
换用特征化表示方法能够解决这一问题。我们可以通过多维度语义特征来定义一个词。
如上图中的6个词语,用了四个语义特征来描述每个词语。所以每个词就可以用一个四维的特征向量来表示。此时可以清晰地看出语义相近的词,其特征向量了也是相近的。
需要说明的是,上图的语义特征是我们手工定义比较直观的举例;但是在实践中这些通政使算法学习来的,而且这些学习的来的特征可能并不具有良好的解释性,但无论如何,算法都可以据此来快速识别词汇之间的相关性。
当我们将单词使用这种高维的特征表示时,这种表示方法叫做词嵌入(word embedding)。之所以叫做embedding,可以想象成每个单词被嵌入(embed)到了一个高维空间内。词嵌入是NLP最重要的思想之一。
将这些用高维特征向量嵌入到一个二维的空间来进行可视化,常用的一种可视化算法是 t-SNE 算法。在通过复杂而非线性的方法映射到二维空间后,每个词会根据语义和相关程度聚在一起。相关论文:van der Maaten and Hinton., 2008. Visualizing Data using t-SNE
词嵌入(Word Embedding)是 NLP 中语言模型与表征学习技术的统称,概念上而言,它是指把一个维数为所有词的数量的高维空间(one-hot 形式表示的词)“嵌入”到一个维数低得多的连续向量空间中,每个单词或词组被映射为实数域上的向量。对大量词汇进行词嵌入后获得的词向量,可用于完成命名实体识别(Named Entity Recognition)等任务。
词嵌入与迁移学习
用词嵌入做迁移学习可以降低学习成本,提高效率。其步骤如下:
- 从大量的文本集中学习词嵌入,或者下载网上开源的、预训练好的词嵌入模型;
- 将这些词嵌入模型迁移到新的、只有少量标注训练集的任务中;这样做的一个好处就是你可以用更低维度的特征向量代替原来的10000维的one-hot向量,现在你可以用一个300维更加紧凑的向量。尽管one-hot向量很快计算,而学到的用于词嵌入的300维的向量会更加紧凑。
- 可以选择是否微调词嵌入。实际中,只有这个第二步中有很大的数据集你才会这样做,如果你标记的数据集不是很大,通常不会在微调词嵌入上费力气。
当你的任务的训练集相对较小时,词嵌入的作用最明显,所以它广泛用于NLP领域。它已经用在命名实体识别,用在文本摘要,用在文本解析、指代消解,这些都是非常标准的NLP任务。
词嵌入在语言模型、机器翻译领域用的少一些,因为对于这些任务,你通常有大量的数据。
最后,词嵌入和人脸编码之间有奇妙的关系,都是类似于通过特征去描述。人脸识别领域和这里的词嵌入有一个不同就是,在人脸识别中我们训练一个网络,任给一个人脸照片,甚至是没有见过的照片,神经网络都会计算出相应的一个编码结果。词嵌入则是有一个固定的词汇表,比如10000个单词,对于向量\(e_1\)到\(e_{10000}\),学习到一个固定的编码,每一个词汇表的单词都有固定嵌入。
词嵌入与类比推理
词嵌入还有一个特性就是可以帮助实现类别推理。类别推理可以帮助人们理解词嵌入做了什么和可以做什么。
比如对于上图的例子,已知Man对应Woman,想要通过类比推理得到King的对应词汇。则有\(e_{man}-e_{woman}\approx=[-2,0,0,0]\),并且\(e_{king}-e_{queen}\approx [-2,0,0,0]\)。由此可以根据Man-Woman类比推断出King-Queen。对于上述的式子\(e_{man}-e_{woman}\thickapprox e_{king}-e_{queen}\),是描述了向量man-woman和向量king-queen 之间的相似程度。
所以,类比推理问题可以转换成求向量\(e_w\),使得\((e_{man},e_{woman})\)和\((e_{king},e_{w})\)相似度最大,即求\(sim(e_{king}-e_{man}+e_{woman})\)相似度最大的向量。
一个常用的用于计算相似度的函数是余弦相似度(cosine similarity)。公式为:
嵌入矩阵
当我们是应用算法学习词嵌入的时候,实际上是通过学习更新的是一个嵌入矩阵(Embedding matrix),记为\(E\)。
加入词汇表的单词是10000个单词,词嵌入的特征是300维的,则嵌入矩阵是一个300x10000的矩阵。如下图所示。
比如我们需要拿到orange的词嵌入的特征向量,就可以用嵌入矩阵与orange的one-hot向量相乘得到。
将词汇表位置为\(i\)的词的one-hot向量表示为\(o_i\),对应的词嵌入后生成的词向量由\(e_i\)来表示,则有
但是在实际计算中,一般也不会用矩阵乘法去计算,因为one-hot元素数量比较大而且大都为0,因此这样做的效率比较低。所以在实践中由专门的函数来从\(E\)种提取特定列。
词嵌入的学习:Word2vec&GloVe
神经概率语言模型
神经概率语言模型(Neural Probabilistic Language Model)构建一个能通过上下文来预测未知词语的神经网络,在训练这个语言模型的同时学习词嵌入。
对于上图中的例子,我们希望预测orange后面的单词。
首先将句子中的每个单词用one-hot 向量表示(当词汇表大小为10000时,one-hot向量维度也是10000),然后把词嵌入矩阵\(E\)与每个词的one-hot向量\(o_i\)相乘得到对应的特征向量\(e_i\),这里设定词嵌入矩阵的行数为300,那么得到的\(e_i\)是300x1的向量。
并将得到的每个词对应的特征向量\(e_i\)垂直排列后输入到神经网络中,也就是300x6=1800个输入,最后再通过softmax输出10000个分类(与词汇表维度保持一致),预测orange后面的单词是其中的那个。
要注意的是,词嵌入的矩阵是我们需要通过梯度下降学习的参数(\(E\)可以通过随机初始化或其他)。此外还有还需要学习的参数有神经网络中的\(W^{[1]}\)和\(b^{[1]}\)以及softmax层中的参数\(W^{[2]}\)和\(b^{[2]}\)。我们就通过这样的模型学习到了词嵌入矩阵。
在实际操作中,可能不会把整个句子都作为输入,而是采用固定大小的历史窗口的做法,即设置上下文的范围。还是以上图为例,当窗口为4时,就用a glass of orange 这四个单词做预测。这样神经网络输入参数就是固定的,可以应对各种长度的句子。
为什么会有效: 可以想象,在训练集中,Orange和Apple后面经常跟着相同的单词(比如juice),因此算法会倾向于将Orange和Apple的词嵌入设置为相似的,这样会更好的拟合模型。
前面的做法是,预测参考的是前文中紧跟着得4个单词(a glass of orange),而target是紧跟着得1个单词(juice)。这对构建语言模型来说是很合理的,但如果不是为了构建语言模型,而仅仅为了学习词嵌入矩阵,预测参考context可以有更多选择:
- 左右相邻的4个单词,比如a glass of orange和to go along with
- 前面的1个单词,比如orange
- 附近的1个单词,比如glass
其中最后一种做法也叫skip gram模型,看起来很神奇,但效果依然很好
Word2Vc
Word2Vc是一种简单且高效的词嵌入学习算法,包括两种模型
- Skip-gram(SG):根据输入词预测目标上下文
- Continuous Bag of Words(CBOW):根据上下文预测目标词
每种语言模型又包含负采样(Negative Sapmling)和分级的softmax(Hierarchical Softmax)两种训练方法。
词嵌入中的元素就是作为参数带入神经网络中训练。
相关论文:Mikolov et. al., 2013. Efficient estimation of word representations in vector space.
Skip-gram
假如在训练集里有这样一条数据:
I want a glass of orange juice to go along with my cereal.
我们要做的是抽取上下文(context)和目标词(target)配对,来构造一个监督学习问题。上下文不一定总是目标单词离得最近的四个或几个单词。我们要从中随机选择一个词作为上下文词,比如选择orange这个词,然后在一定词距范围即窗口内选另一个词作为目标词。可能你正好选择到了juice作为目标词,也可能你选到了my作为目标词,也可能你选择到了前面的词glass作为目标词。
所以我们的监督学习问题是给出一个上下文中的词作为输入,让算法预测一定词距内(窗口内)的其他单词(target),也就是根据输入词预测上下文中的目标词。这个预测也许并不容易,但是我们构建模型的目标也不在于预测,而在于通过训练模型学习出一个好的词嵌入矩阵。
下面是skim-gram的细节:
加入词汇表大小是10000,输入的上下文词的one-hot向量\(o_c\),与词嵌入矩阵\(E\)相乘得到嵌入向量\(e_c\),然后把\(e_c\)输入到softmax层,输出一个10000维的\(\hat y\),表示预测的概率。
设选取上下文中的词为\(c\),该词一定距离内的上下文中选取的目标对象为\(t\),则预测不同单词的概率是:(exp函数是以e为底求指数)
\(\theta_t\)是一个与输出t有关的参数,即某个词\(t\)和标签相符的概率是多少。其中省略了用以纠正偏差的参数。损失函数仍选择交叉熵:
在此softmax分类中,每次计算条件概率时,需要对词汇表中所有的词做求和操作,因此计算量很大。解决方案之一是使用一个分级的softmax分类器,形如二叉树,在实践中一般使用霍夫曼树,而非平衡二叉树,常用词一般分布在顶部。
对输入context的抽样
如果在语料库中随机均匀采样得到选定的词 \(c\),则 'the', 'of', 'a', 'and' 等出现频繁的词将影响到训练结果。因此,采用了一些策略来平衡选择。
CBOW
CBOW 模型的工作方式与 Skip-gram 相反,它获得中间词两边的的上下文,然后用周围的词去预测中间的词,这个模型也很有效,也有一些优点和缺点。
总结下:CBOW是从原始语句推测目标字词;而Skip-Gram正好相反,是从目标字词推测出原始语句。CBOW对小型数据库比较合适,而Skip-Gram在大型语料中表现更好。 (下图左边为CBOW,右边为Skip-Gram)
负采样
为了解决softmax计算慢的问题,Word2Vc的作者后续提出了负采样(Negative Sampling)模型。它和skip-gram相似,但是用了一个更加有效的学习方法。
负采样模型重新定义了监督学习问题:给定两个单词,其中一个是句子中的单词如orange和juice,预测这个单词对是否是一对上下文词-目标词(context-target)
模型的训练样本:
-
首先生成一个正样本(Positive Example),即该样本是一个context-target。先从句子中选取一个词作为context,然后在一定词距内,即窗口内选取target词。比如orange-juice,我们把正样本标记为1。
-
然后使用和正样本相同的context词生成负样本(Negative Example),负样本的target词是从词汇里随机选取。比如生成的负样本可以是orange-the,我们把负样本标记为0。同样的方法,生成\(k\)个 负样本,可能是:orange-book, orange-the, orange-or。由于是在很大的词典中随机选择的,我们总认为是负样本,因此即便上面的orange-or的例子,or其实是Orange的target,我们依然标记为0。最终形成如下记录:
对于负样本\(k\)的选择,在数据量较小时\(k\)推荐为5-20,在数据量比较大时\(k\)推荐2-5。
所输入标签\(x\)是context-target对,输出标签\(y\)为判断输入是正采样还是负采样。那么,这个算法就是要分辨这两种不同的采样方式,这就是如何生成训练集的方法。
为了定义模型,我们将使用记号\(c\)表示上下文词,记号\(t\)表示可能的目标词,我再用\(y\)表示0和1,表示是否是一对上下文-目标词。定义一个逻辑回归模型,给定输入的\(c,t\),对er的条件下,\(y=1\)的概率,即:
每个context-target对都用sigmoid输出为正样本的概率。之前的模型中的训练每次都要更新n维的多分类softmax单元(n为词汇表中词的数量),现在每次只需要更新k+1个二分类的sigmoid单元,计算量就大大降低了。这个技巧就叫负采样。因为你做的是,你有一个正样本词orange和juice,然后你会特意生成一系列负样本。
关于负样本的选取,一种办法是从单词表里均匀分布采样,不考虑词频;另一种办法是根据经验概率采样名,会导致常用词(如of、the)被采样的频率很高。作者推荐采用以下公式,而非经验频率或均匀分布:
其中\(f(w_i)\) 代表语料库中单词\(w_i\)出现的频率。通过取3/4次方,使得既考虑到单词的语料库频率,又能增加低频单词被选取的概率。更加平滑,能够增加低频词的选取可能。
GloVe
GloVe(Global Vectors)是另一种更简便的词嵌入算法。GloVe模型基于语料库统计了词的共现矩阵\(X\),\(X\)中的元素\(X{ij}\)表示单词\(i\)和单词\(j\)为“context-target“对的次数。之后,用梯度下降法最小化以下损失函数:
其中,\(\theta_i\)、\(e_j\)是单词\(i\)和单词\(j\)的词向量;\(b_i\)\(、b_j\)、\(f(X_{ij})\)是用来避免\(X_{ij}=0\)时\(log(X_{ij})\)为负无穷大、并在其他情况下调整权重的函数。并且为我们约定\(X_{ij}=0\)时,\(f(X_{ij})=0\),上述的损失函数也为0。
当两个词为context-target对时,就代表了这两个词是在一定词距范围内的即两个词在一个窗口内。当窗口大小为上下文10个单词前后的范围,在这种情情况下\(X_{ij}\)、\(X_{ji}\)完全相等的。当上下文范围是前后的一个词,那可能\(X_{ij}\)、\(X_{ji}\)没有这种对称性。
因此,\(\theta_i\)、\(e_j\)是完全对称的,所以在训练的时候可以一致地初始化二者,使用梯度下降法处理完以后取二者的平均值作为此嵌入向量。
最后需要说明的是,使用各种词嵌入算法学习到的词嵌入向量实际上大多都超出了人类的理解范围, 难以从某个值中看出来与语义相关的程度。
情感分类
情感分类的任务就是分析一段文本对某个对象的情感是正面的还是负面的。是应用包括舆情分析、民意调查、产品意见调查等。情感分类的问题之一就是标记好的训练数据不足。但是有了词嵌入得到的词向量,中等规模的训练数据也能构建出一个效果不错的情感分类器。
下图是一个情感分类的例子,通过用户的评x,判断用户对服务的打分y。
我们可以创建上图所示的这样一个模型。用每个词的one-hot向量与词嵌入矩阵相乘后获得对应的词嵌入向量。然后将每个词的词嵌入向量求和或者求平均值,输入到softmax分类单元,预测打分结果。这种方法的优点是适用于任何长度的文本;缺点是没有考虑词的顺序,对于包含了多个正面词语的负面评价,很容易得到错误的结果。
“Completely lacking in good taste, good service, and good ambience.” 这里就有很多good但是是一个负面评价。
为此,我们通过RNN改进,实现更好的情感分类器:
将转换后的词嵌入向量,输入到一个”many-to-one“的RNN网络,通过softmax分类,这样就兼顾了词本身的意思和语序。
由于词嵌入是在一个更大的数据集里训练的,在情感分类中应用词嵌入,更好的泛化一些没有见过的新的单词。即使语句中出现了训练时没有见过的单词,但是模型也可以很好的泛化。
词嵌入除偏
语料库中可能存在性别歧视、种族歧视、性取向歧视等非预期形式偏见(Bias),这种偏见会直接反映到通过词嵌入获得的词向量。例如,使用未除偏的词嵌入结果进行类比推理时,"Man" 对 "Computer Programmer" 可能得到 "Woman" 对 "Housemaker" 等带有性别偏见的结果。词嵌入除偏的方法有以下几种:
-
中和本身和性别无关的词
对于“医生(doctor)”、“老师(teacher)”、“接待员(receptionist)”等本身与性别无关词汇,可以中和(Neutralize)其中的偏见。首先用“女性(woman)”的词向量减去“男性(man)”的词向量,得到的向量\(g=e_{woman}-e_{man}\)就代表了“性别(gender)”。假设现有的词向量维数为 50,那么对某个词向量,将 50 维空间分成两个部分:与性别相关的方向\(g\)和与\(g\)正交的其他49个维度。如下左图:
而除偏的步骤,是将要除偏的词向量(左图中的 \(e_{receptionist}\)在向量 \(g\)方向上的值置为0,变成右图所示的\(e_{receptionist}^{debiased}\)。
公式如下:
\[e^{bias\_component}=\frac{e*g}{||g||^2}*g\\ e^{debiased}=e-e^{bias\_component} \] -
均衡本身与性别有关的词
对于“男演员(actor)”、“女演员(actress)”、“爷爷(grandfather)”等本身与性别有关词汇,中和“婴儿看护人(babysit)”中存在的性别偏见后,还是无法保证它到“女演员(actress)”与到“男演员(actor)”的距离相等。对这样一对性别有关的词,除偏的过程是均衡(Equalization)它们的性别属性。其核心思想是确保一对词(actor 和 actress)到 \(g_⊥\) 的距离相等。
公式: