本文是一篇翻译文章,原文地址(https://towardsdatascience.com/why-do-we-use-embeddings-in-nlp-2f20e1b632d2).
自然语言处理(NLP)是机器学习(ML)的一个子领域,NLP任务通常以文本形式处理自然语言,而文本本身由较小的单元(如单词和字符)组成。而要处理的文本数据是有问题的,因为我们的计算机,脚本和机器学习模型无法以任何人类的角度阅读和理解文本。
比如当我读到"猫"这个词时,就会想象到许多内容——它是一种可爱的小毛茸茸的动物,喜欢吃鱼,或者我的房东不允许养猫等。但是,这些语言关联是数百万年进化过程中相当复杂的神经相互影响的结果,而我们的机器学习(ML) 模型必须从零开始,它对词义没有预先构建的理解。
理想情况下,无论我们想出什么数值表示方法,在语义上都会是有意义的——数值表示法应该尽可能多地捕获单词的语言意义。精心挑选的、信息丰富的输入表示形式会对整体模型性能产生巨大影响。
词嵌入(word embedding)是解决此问题的主要且普遍的方法,以至于在任何 的NLP 项目中实际上都使用了词嵌入的方法。无论你是在文本分类、情感分析还是机器翻译等任务中,你都可以下载预先计算好的嵌入数据(如果你的问题相对标准),或者考虑使用哪种方法从数据集中计算你自己的词嵌入。
不谈论任何用于计算词嵌入的特定算法(假设你从来没有听说过 word2vec 或 FastText 或 ELMo),这篇文章将回到基础知识来回答以下问题:
当给定 10000 个单词的词汇表,用数字表示每个单词的最简单方法是什么?
10000个词汇的单词表
那么最简单的就是为每个单词分配一个整数索引:
10000个有词汇索引的单词表
给定这种单词到整数的映射,我们可以将单词表示为数字向量,如下所示:
下边是一些示例:
此过程称为one-hot编码。你可能还听说过这种方法用于表示多分类问题中的标签。
现在,假设我们的NLP项目正在构建翻译模型,我们想将英语输入语句"the cat is black"翻译成另一种语言。我们首先需要用one-hot编码来表示每个单词。我们首先将查找第一个单词“ the”的索引,然后发现在我们的10,000长词汇列表中的索引为8676.
然后,我们可以使用长度为10,000的向量表示单词“ the”,其中只有8676位置为"1",其他位置为"0".
我们对输入句子中的每个单词进行索引查找,并创建一个向量来表示每个输入单词。整个过程看起来像是GIF:
使用one-hot编码"the cat is black"的过程
请注意,此过程为每个输入单词生成了非常稀疏的(几乎为零)特征向量(此处术语“特征向量”,“嵌入”和“词表示”可互换使用)。
这些one-hot vector是将单词表示为实值数字向量的快速简便方法。
问题来了:如果你想生成整个句子(而不只是每个单词)的表示,该怎么办?最简单的方法是连接或平均句子的组成词嵌入(或两者的混合)。更高级的方法将顺序读取每个单词的嵌入,比如 encoder-decoder RNN模型,以便通过变换的层级来逐步建立句子含义的密集表示(有关ELMo句子嵌入的快速概述,请参阅此帖子)
我们已经完成one-hot编码,并成功地将每个单词表示为数字向量。许多NLP项目已经做到了这一点,但是最终结果却是中等的,尤其是在训练数据集很小的情况下。这是因为one-hot vectors不是很好的输入表示方法。
这些要点是相关的,计算和词汇量问题可以被视为技术问题,而相似性问题更像是“最好拥有”的点。
one-hot vector密集嵌入的问题?
这意味着嵌入使我们可以构建更通用的模型,而不是网络需要为学习断开连接的输入而学习许多不同的方法,而让相似的词“共享”参数和计算路径。
在某些情况下,最好对嵌入使用稀疏的one-hot编码。为了解释Yoav Goldberg在他的神经网络中的NLP引物,如果:
那么使用稀疏的one-hot编码可能不是最坏的主意。
一个独立但相关的观点:当然,对于分类数据进行预处理时,one-hot编码始终是有意义的,因为许多ML模型无法直接处理分类数据(例如文本标签)。你仍将使用它们将多类标签向量转换为许多二进制类向量,或将少数分类特征向量转换为其二进制形式。
现在,我们已经讨论了one-hot vector及其缺陷,下面我们来讨论使用密集的,语义上有意义的特征矢量来表示单词的含义。
如果我们从词汇表中选取5个示例单词(例如,单词“ aardvark”,“ black”,“ cat”,“ duvet”和“ zombie”)并检查通过上述one-hot编码方法创建的嵌入矢量,结果将如下所示:
使用one-hot编码的词向量。每个单词都由一个几乎为零的向量表示,除了该单词在词汇表中的索引所指示的位置中只有一个“ 1”。注意:并不是说“black”,“cat”和“duvet”具有相同的特征向量,而是这里看起来像这样。
但是,当人类说某种语言时,我们知道单词是这些丰富的实体,具有许多层次的含义和含义。让我们为这5个单词制作一些语义特征。具体来说,让我们将每个单词的四种语义(animal,fluffiness,dangerous,spooky)的值设置为介于0和1之间:
为词汇表中的5个词构建的语义特征
然后,解释一下这几个例子:
我们工作的要点:
在2维或3维空间绘制词特征
这是一个自己制作的示例,但实际的嵌入算法当然会自动生成输入语料库中所有单词的嵌入向量。如果你希望,你可以将 word2vec 等词嵌入算法视为单词的不受监督的特征提取器。
这篇文章不会描述这些算法是如何工作的,但核心思想是,在类似上下文中使用的单词将得到类似的表示形式。也就是说,以类似方式使用的单词将紧密放置在高维语义空间中,这些点将聚集在一起,它们彼此之间的距离将很近。
Word Emdedding算法通常要求你设置希望嵌入的维度数 - 那么合适且正确的维度应该是多少?
直观地是,你输入的类型更多得到的维度也更多。因此,如果你正在计算词的嵌入(其中语料库中可能有数万种类型),则需要更多维度,而如果你计算词性部分标记(如"名词","动词","形容词")的嵌入,则这些类型类型并不少。例如,在流行的 Python NLP 库 NLTK 中,只有 35 种词性(POS),你可能不需要太多的维度,就可以很好地表示每个 POS 类型。
嵌入的维度应该为多少实际上被证明是一个经验问题,而最优数还没有从理论上计算出来。这里的权衡标准是准确性和计算问题:
在实践中,人们使用尺寸在 50 到 500 左右的词嵌入向量(一般经常取 300 个),有时对于竞争非常激烈的系统,可以试图从模型中挤出尽可能多的嵌入向量。
与此相关的是,鉴于这些语义空间通常非常高维,应该如何直观地看到它们中发生了什么?人不能看到超过 3 个维度。
“To deal with hyper-planes in a 14-dimensional space, visualise a 3-D space and say ‘fourteen’ to yourself very loudly. Everyone does it.” - Geoff Hinton
你可以随机选择两个或三个要素,并在这两个或三个轴上绘制点。但是,由于特征/轴通常无法解释,因此你不知道选择哪些要素。此外,单词的位置可能会因你选择的特定轴而变化很大,因此,如果你随机选择几个轴,你就不会获得准确的单词位置。
在实践中,人们通常会使用降维方法(如 t-SNE 或 PCA)将高维嵌入点投影到低维空间中(同时丢失信息)。重要的是,它允许你提取每个单词的两个坐标(比如说从300维降到2维),然后你可以使用 2D 散点图轻松可视化。有很多不错的教程,比如这个。
总结说来,词嵌入:
以上就是文章的翻译,欢迎指正。