课程6. 上下文词嵌入 Word2Vec
课程计划:
- 文本数据的特征;
- 构建词语的信息表征. 词袋模型(Bag of Words, LSA)
- 上下文嵌入. Word2vec
- 在实践中使用预训练的词向量表示
文本数据的特征
到目前为止,我们已经处理了以表格形式表示的数据类型(在传统机器学习中)和图像。我们了解了哪些机器学习模型和神经网络类型最适合这些类型的数据。
让我们回顾一下如何使用神经网络的分类问题作为例子来解决各种机器学习问题:
-
在输入中我们有一些描述一些对象的训练样本。对于训练样本的每个对象都有一组特征和一个目标变量——这就是我们学习预测的内容。
-
我们建立一个神经网络,它以数值表示的特征作为输入,并在输出中得到目标变量的一些预测。
-
接下来,我们在一个特殊的验证样本上选择网络超参数(例如隐藏层的数量和大小、训练周期数、优化算法等):对训练样本进行训练,并在验证样本上评估质量。接下来,我们固定在验证样本上显示最佳结果的超参数集。
-
接下来,您可以在单独的测试样本上评估训练模型的质量。
在这种情况下,需要注意的是,神经网络是一个数学模型。数值被馈送到它作为输入。它利用一些函数(线性和非线性)处理这些数值,并得到一个或多个数值作为输出。
当我们使用表格或图片时,一切都非常简单。这些数据已经以某些数值向量或矩阵(一般情况下为张量)的形式呈现。
但是如果我们使用一些非数字值(例如文本)作为特征会怎样?我们需要以某种方式学习处理文本,获得一些可以输入到神经网络的数字表示。今天我们将讨论如何获得文本的这种数值表示。
文本是另一种类型的数据。并且它在机器学习中的处理与处理图像和表格数据不同。为了理解为什么会这样,让我们重点介绍一下文本的主要属性以及它与其他类型数据的区别:
- 文本是来自有限字母表的标记序列,即序列的所有元素都采用离散值(标记是分类特征)。
- 文本的长度可以不同。
- 文本包含时间成分:在一定时间段内,文本从左到右阅读(或根据语言的不同,以另一个方向阅读。但重点是有一个方向)。
如何处理文本
要将文本数据输入机器学习模型(特别是神经网络),您需要以某种方式将文本表示为数字序列。如何才能做到这一点?
请注意,文本是一系列标记。标记可以是:
- 信件;
- 词语的部分;
- 字;
- 短语
- 句子;
- …
事实证明,文本编码任务可以简化为标记编码任务。然后将文本表示为标记序列,并从编码标记序列中组装出文本编码。
接下来我们将讨论如何对标记进行编码。
单词的矢量表示
在本节中,我们将讨论如何将标记和文本表示为数字向量的一些想法。以及如何使用这些token来解决与文本相关的问题(例如文本分类)。
One-hot encoding & Bag of Words (BoW)
独热编码和词袋(BoW)
将标记表示为向量的最简单的想法之一是独热编码。以下是全部内容:
让我们创建一个固定大小的字典。假设词典包含 n=50,000 个单词。
现在我们将字典中的每个单词表示为大小为
n
n
n 的向量。在字典中的第
i
i
i 个单词的向量中,除了第
i
i
i 个坐标处的唯一为1之外,该向量将包含所有零:
这是一种非常简单的表示单词的方式。可以立即发现以下缺点:
- 词向量不能反映单词的含义。
- 无法衡量两个单词在含义上的“相似性”(所有单词的向量都是彼此正交的);
- 向量非常稀疏,需要大量额外的内存;
- 词典大小有限;
- 无法处理词典中未收录的单词;
- 当改变字典大小时,需要重新计算向量。
显然,还存在着很多的不足。接下来我们将讨论如何表示单词来弥补这些不足。但首先,让我们讨论一下如何从单词的独热编码中获取整个文本的编码。
这很简单:一个句子的向量是其单词向量的总和。
这种文本编码称为词袋。然后,使用该文本表示,可以训练机器学习模型。例如,线性/逻辑回归甚至神经网络。
很明显,Bag of Words 继承了 One-Hot Encoding 的缺点。即:
- 句子向量不能很好地反映句子的含义。不考虑词序;
- 向量非常稀疏,需要大量额外的内存;
- 固定字典大小。
- 字典中未收录的单词无法处理。
- 当改变字典大小时,需要重新计算向量。
这里我们要注意以下几点:原则上,可以使用降维方法来降低 BoW 向量的维数。例如,PCA 或TSNE。
关于 BoW 不提供信息的另外一个考虑因素是,不同的词对于文本可能具有不同的重要性。 BoW 没有考虑到这一点。
在上面的例子中,几乎所有单词的值都是 1,即这种观点假设所有单词对于理解两篇文本都是相同的,但事实并非如此。例如,可以合理地假设冠词和连词在所有文档中都很常见,因此它们不会对特定句子的含义产生很大影响。逻辑上可以假设它们的“权重”(在文本的矢量表示中与这些词相对应的值)应该更小。
现在让我们继续讨论构建信息词向量表示的其他想法。
关于构建词向量表示的更多想法
Tf-iDF
构建单词和文本的信息向量表示的最重要的思想之一是 Tf-iDF。这个想法基于关于如何在构建单词和文本的向量表示时考虑单词对于特定文本的重要性的考虑。 Tf-iDF 长期以来一直被积极用于文本处理。 Tf-iDF 设计还允许解决诸如文档排名和从文档中提取关键字等问题。
有关 Tf-iDF 的更多信息,请参见此处:
潜在语义分析 (LSA)
LSA 是获取单词和文本的信息向量表示的另一个简单的想法。它由以下内容组成。让我们构建一个文档词矩阵:
现在我们将其分解为SVD分解:
事实证明,通过这种分解,矩阵
U
U
U 的行可以被视为文档向量,矩阵
V
T
V^T
VT 的列可以被视为词向量。 “可以认为”是指这些向量实际上会体现出单词和文本的含义。意义相近的词的向量会很接近,意义相远的词的向量会按照欧几里得距离很远。
现在:SVD 分解具有以下属性:矩阵 S S S 的对角线元素按降序排列。它们被称为奇异值。很显然,矩阵 S S S对角线上的数字越小,矩阵 U U U和 V T V^T VT对应的行和列对最终乘积的贡献就越小。
因此,我们只需将矩阵 U U U 和 V V V 的前行和前列分别保留为 m m m 即可。然后我们得到文档和文本的向量将小于长度 m m m。同时,大部分信息也会被保留在其中。
下面是经过 LSA 处理后,将向量维数降低至 m=2 后的文档和词向量的可视化。可以看出,单词和文档按主题分为三类:
我们来看看LSA的优点和缺点:
优点:
- 向量有意义;
- 能够在不显著损失质量的情况下减小嵌入的尺寸。
缺点:
- 文档数量多,计算复杂度高;
- 固定字典大小;
- 当改变文档集合时,需要重新计算向量;
- 该方法的概率模型与现实不符。它意味着单词和句子在某种意义上是呈正态分布的。但事实上情况似乎并非如此:实际上分布更像是泊松分布。
总结:在本文中你可以阅读到更多关于 LSA 的内容。
让我们继续讨论下一个想法:如何创建单词的信息向量表示。
上下文词嵌入. Word2Vec
上下文嵌入
让我们考虑三句话:
- 玛莎驾驶 ____________
- 轮胎 ____________ 被刺破了
- ____________ 有一个漂亮的白色框架。
我们还来看看这些句子中空缺的四个候选词:自行车、摩托车、汽车(机器)和马。问题:这些单词中的哪一个可以填补哪个空白?
这里产生了这样的想法:单词的含义取决于其使用的上下文。这就是根据上下文构建单词向量表示的想法的由来。
让我们思考一下如何根据上下文构建词向量。首先想到的想法是这样的:假设我们有一个文本语料库和一个大小为 n n n 的词典。让我们计算一下字典中的每个单词在该文本语料库中与字典中其他单词一起出现的次数。我们将构建一个大小为 n ⋅ n n \cdot n n⋅n 的矩阵,在该矩阵的第 i i i 行与第 j j j 列的交叉点处有一个数字,该数字反映词典中的第 i i i 个单词在文本语料库中的第 j j j 个单词的上下文中出现的次数。
让我们概述一下这种方法的优点和缺点:
优点:
- 矢量开始体现词语的含义!可以使用欧几里得距离比较它们的相似度;
缺点:
- 向量仍然相当稀疏,需要大量额外的内存;
- 字典大小有限。词典中没有收录的单词无法被处理;
- 当改变字典大小时,需要重新计算向量;
- 罕见词向量信息量不大。
还要注意,降维方法(PCA / TSNE)也可以应用于这种方法:
好的,它已经更好了:嵌入变得更具信息量。现在让我们注意以下几点:到目前为止我们所做的一切都是基于一些考虑,构建单词/文档的向量/矩阵,以某种方式反映单词/文档的含义。
如果我们尝试学习单词/文档向量会怎样?
Word2Vec
所以让我们制定我们想要的:
我们想要学习反映单词含义的低维词向量:它们可以使用某种度量相互比较。
我们将这种学习到的向量称为词嵌入。
我们将如何学习这样的向量:我们将教神经网络根据一个单词来预测可能在上下文中出现的单词(围绕这个词)。
神经网络将单词 X X X作为输入,并输出词典中所有单词的概率分布。输出中出现单词 Y Y Y的概率越大,在单词 X X X的上下文中遇到这个单词 Y Y Y的可能性就越大。
为了训练这样的神经网络,我们需要一个数据集——一组文本。 我们将使用大小为 5 的滑动窗口遍历数据集,并在窗口的每个位置使用中心词,教神经网络预测当前窗口中的单词。
因此,该问题的正式表述如下:
- 设置分类任务。类别数——字典大小 n n n。
- 神经网络以一个单词作为输入,产生 n n n个值——词典中单词的分布。
- 损失函数是网络产生的分布与正确分布(one-hot 向量)之间的交叉熵
作为神经网络,我们将采用两层全连接神经网络,层间没有激活函数。接下来我们将了解为什么这很重要。
该神经网络将以独热向量的形式接受一个单词作为输入。输出将是一个长度为 n n n 的向量,其概率分布在字典中的单词上。
假设我们训练了这样一个神经网络。现在让我们了解一下词嵌入在其中的位置。
为了做到这一点,让我们以稍微不同的方式描述我们的神经网络:
假设单词 into 为词典中的第
i
i
i 个单词,单词 banking 为第
j
j
j 个单词。注意,将单词into的one-hot向量与矩阵
A
A
A(网络第一层)相乘时,得到的结果应该是矩阵
A
A
A的第
i
i
i行。还要注意,神经网络输出向量的第 j 个元素(对应单词 banking)是第一层的输出与矩阵
B
B