Word2Vec —— 深度学习的一小步,自然语言处理的一大步

bigdataway 提交于 周二, 06/19/2018 - 18:17

雷锋网按:本文为雷锋网字幕组编译的技术博客,原标题 A、Word2Vec — a baby step in Deep Learning but a giant leap towards Natural Language Processing,作者为机器学习工程师 Suvro Banerjee

翻译 | 于志鹏 林骁    校对 | 程思婕   整理  |  孔令双

原文链接:

https://towardsdatascience.com/word2vec-a-baby-step-in-deep-learning-but-a-giant-leap-towards-natural-language-processing-40fe4e8602ba

引言

Word2Vec 模型用来学习单词的向量表示,我们称为「词嵌入」。通常作为一种预处理步骤,在这之后词向量被送入判别模型(通常是 RNN)生成预测结果和执行各种有趣的操作。

为什么要学习 word2vec

图像和声音处理系统所需丰富、高维的数据集,按各原始图像的像素强度被编码为向量的形式,所有信息都被编码在这样的数据中,因此就可以在系统中建立各种实体(如 cat 和 dog)之间的关系。

但是,传统的自然语言处理系统通常将单词视为离散的原子符号,所以 cat 可以被表示为 Id537,dog 可以表示为 Id143。这些编码是任意的并且不能向系统提供任何关于各个原子符号之间关系的信息。这意味着,模型在处理 dogs 的数据时不能与模型已经学习过的 cats 的特征联系起来(如它们都有是动物,都有四条腿,都是宠物等等)。

将单词表示为唯一的、离散的 ID 还会进一步导致数据稀疏,还意味着我们可能需要更多的数据才能成功训练统计模型。使用向量表示就可以避免这些问题。

让我们来看一个例子

传统的 NLP 方法涉及许多语言学领域知识,要求你理解诸如「音素」及「词素」等术语,因为语言学中有很多分类,音素学和词素学是其中的两种。让我们来看看传统的 NLP 方法如何尝试理解下面的单词。

假设我们要获取关于单词的一些信息(诸如它所表达的情绪、它的定义等),运用语言学的方法我们将词分为 3 个部分。即前缀、后缀、词干。

比如,我们知道「un」前缀表示相反或否定的意思,我们也知道「ed」可以指定表示单词的时态(过去时)。我们可以从「interest」的词干中很容易的推断出整个词的含义和表达的情感. 是不是非常简单?然而,当考虑所有不同的前后缀时需要非常娴熟的语言学家来理解所有可能组合的含义。

深度学习,本质上就是表示学习。我们将要采用一些方法通过大数据集的训练来创建单词的表示。

词向量

假设我们用一个 d 维向量表示每一个单词,假设 d=6。我们想要为句子中的每个不重复单词创建单词词向量。

现在来考虑一下如何赋值,我们希望可以用某种方式来表示这个单词和它的上下文、含义、语义。一种方法是创建一个共生矩阵。

共生矩阵是这样一种矩阵,它包含这个词在所有语料库(或训练集)中和所有其他词组合出现的次数。我们来看一下共生矩阵的样子。

通过上面这个简单的共生矩阵的例子,我们可以获得很多相当有用的信息。比如,我们注意到「love」和「like」这两个词向量中都含有若干个 1,这是对他们所接名词(NLP 和 dogs)的记数。对「I」的记数也含若干个1,因此表明这个单词一定是某个动词。当处理多句的大数据集时,你可以想象这种相似性会变得更加清晰,比如「like」、「love」和其他同义词将具有相似的词向量,因为他们在相似的语境中。

目前,虽然我们有了一个很好的开端,但是我们也要注意到每个单词的维度将随着语料库的增大而线性增加。如果我们有 100 万个单词 (在 NLP 的标准中并不是很多),我们将会有一个 100 万*100 万大小的矩阵,并且是非常稀疏的(大量 0 元素)。在存储效率方面这个显然不是最好的方案。在寻找表示这些词向量的最佳方法中有很多改进。其中最著名的就是 Word2Vec 。

正式介绍

向量空间模型(VSMs)在连续向量空间中表示(嵌入) 单词,其中语义相似的单词被映射到临近点(嵌入在彼此附近)。VSMs 在 NLP 发展中有着悠久的历史,但都依赖于分布式假设,该假设指出,出现在相同语境中的单词具有相似语义。利用这一原则的方法可以分为两类:

  1. 1.基于记数的方法(例如:潜在语义的分析);

  2. 2.预测方法(例如:神经概率语言模型)

他们的区别是--

用计数的方法计算某个词在大型文本语料库中与其相邻词汇共同出现的频率的统计数据,然后将这些统计数据的每个词映射为小且密集的向量。  

预测模型直接尝试根据学习的小密集嵌入向量(考虑模型的参数)来预测来自其邻居的单词。

Word2vec 是一种特别有效的计算预测模型,用于从原始文本中学习单词嵌入。它有两种形式,即连续字袋模型(CBOW)和 the Skip-Gram 模型。在算法上,这些模型是相似的,除了 CBOW 从源上下文单词中预测目标单词,而 the skip-Gram 相反并预测来自目标单词源上下文的单词。

在接下来的讨论中,我们将重点讨论 skipg 模型。

数学运用

传统上,神经概率语言模型使用最大似然原理进行训练,以 softmax 函数的形式使给定前面的单词 h(「history」)的下一个单词 wt(「target」)的概率最大化。

利用 score(wt, h) 计算目标词 wt 与上下文 h 的兼容性(通常使用点积运算)。

我们通过在训练集上最大化它的对数似然来训练这个模型。所以,我们最大化以下损失函数。

这为语言建模提供了一个合适的标准化概率模型。

这个相同的论点也可以用稍微不同的公式来表示,它清楚地显示了为了使这个目标最大化而改变的变量(或参数)。

我们的目标是找到一些词汇表示,这些词汇可以用于预测当前单词的周围词汇。特别是,我们希望最大化我们整个语料库的平均对数概率:

这个方程从本质上说,有一些概率 p 观察当前单词 wt 的大小为 c 的窗口内的特定单词。这个概率取决于当前单词 wt 和参数θ的一些设置(由我们的模型确定)。我们希望设置这些参数θ,以便在整个语料库中这个概率最大化。

基本参数化:Softmax 模型

基本 skip-gram 模型定义了通过 softmax 函数的概率 p,正如我们前面看到的那样。如果我们认为 wi 维数为 N 和θ的单热编码矢量,并且它是一个 N×K 矩阵嵌入矩阵,这表示我们的词汇表中有 N 个词,而我们学习的嵌入具有维数 K,那么我们可以定义 -

值得注意的是,在学习之后,矩阵theta可以被认为是嵌入查找矩阵。

在架构方面,它是一个简单的三层神经网络。

  1. 搭建三层网络结构(一个输入层,一个隐藏层,一个输出层)

  2. 传入一个单词,并让它训练其附近的单词

  3. 移除输出层,但保留输入层和隐藏层

  4. 接着,从词汇表中输入一个单词。隐藏层给出的输出是输入单词的「单词嵌入」

这种参数化有一个主要的缺点,限制了它在大型的语料库中的用处。具体来说,我们注意到为了计算我们模型的单个正向通过,我们必须对整个语料库词汇进行总结,以评估 softmax 函数。对于大型数据集来说这是非常奢侈的,所以我们为了计算效率考虑这个模型的替代近似。

提高计算效率

对于 word2vec 中的特征学习,我们不需要完整的概率模型。CBOW 和 skip-gram 模型是使用二分类目标(逻辑回归)来训练的,以在相同的上下文中将真实目标词语(wt)与 k 个虚数(干扰)词语 w 进行区分。

在数学上,该操作是对每个对象进行最大化。

当模型将高概率分配给真实词,并将低概率分配给噪音词,这个目标被最大化。 从技术上讲,这被称为负采样,它提出的更新近似于极限中softmax函数的更新。 但是在计算上它特别有吸引力,因为计算损失函数现在只能根据我们选择的噪音词的数量(k)而不是词汇表(V)中的所有单词, 这使它训练速度更快。 像Tensorflow这样的软件包使用了一种非常相似的损失函数,称为噪声对比估计(NCE)损失。

Skip-gram 模型的直观感受

作为一个示例,我们需要考虑数据集-

the quick brown fox jumped over the lazy dog

我们首先形成一个单词数据集和它们出现的上下文。现在,让我们坚持使用 the vanilla 定义,并将「上下文」分别将单词窗口定义为目标单词左侧和右侧。使用窗口大小为 1,我们就有了 (context, target) 对的数据集。

([the, brown], quick), ([quick, fox], brown), ([brown, jumped], fox), ...

回想一下,skip-gram 会颠倒上下文和目标,并试图从目标词中预测每个上下文单词,因此任务将从「quick」,「quick」和「fox」中预测「the」和「brown」」。

因此我们的数据集成为(input,output),如下所示:

(quick, the), (quick, brown), (brown, quick), (brown, fox), ...

目标函数是在整个数据集上定义的,但我们通常使用随机梯度下降(SGD)对每个示例(或 batch_size 示例的「minibatch」进行优化,其中通常为 16 <= batch_size <= 512)进行优化。让我们来看一下这个过程的一个步骤。

让我们想象一下,在训练步骤中,我们观察上面的第一个训练案例,其中的目标是快速预测。我们通过从一些噪声分布(通常是单字符分布)中选择 num_noise 噪声(对比)例子的数目来选择(该单元假设每个词语的出现与所有其他词语的出现无关,也就是说我们可以将生成过程看作是一个骰子序列滚动序列 P(w)。

为了简单起见,我们假设 num_noise = 1,我们选择 sheep 作为一个干扰的例子。接下来我们计算这对观察到的和有噪声例子的损失,即在时间步骤「t」的目标变成 -

我们的目标是对嵌入参数θ进行更新以最大化该目标函数。 我们通过推导关于嵌入参数θ的损失梯度来做到这一点。

然后,我们通过向梯度方向的移动来更新嵌入参数。当这个过程在整个训练集上重复时,这会对每个单词产生「移动」嵌入向量的效果,直到模型成功地区分真实单词和噪音单词为止。

我们可以通过将它们向下投影到 3 维来可视化学习向量。当我们观察这些可视化变量时,很明显,这些向量捕获了一些关于单词的语义信息以及它们之间的关系,在实际应用上时非常有用的。

参考资料

  1. Word2Vec的Tensorflow实现

  2. 词语和短语的分布式表征及其组合性 - Tomas Mikolov,Ilya Sutskever,Kai Chen,Greg Corrado 和 Jeffrey Dean 的研究论文

  3. Aneesh Joshi对word2vec的实用指南

  4. Adit Deshpande自然语言的评论

  5. Rohan Verma的语言模型

雷锋网 (公众号:雷锋网) 字幕组编译。

雷锋网版权文章,未经授权禁止转载。详情见 转载须知

分类