本章将介绍最常见的 自然语言理解 方法,并讨论每种方法的优缺点,包括基于规则的方法、基于统计机器学习的方法和基于深度学习的方法。除此之外,本章还会讨论一些目前比较流行的预训练模型,例如 基于Transformer的双向编码器表示 (Bidirectional Encoder Representations from Transformers,BERT)模型及其衍生模型。通过本章学习,你将了解NLU不是一个单一的方法,而是一系列的方法集合,这些方法适用于不同的任务。
本章将介绍以下内容:
❑基于规则的方法
❑传统的机器学习算法
❑深度学习方法
❑预训练模型
❑选择自然语言理解方法需要考虑的因素
基于规则的方法 的核心是语言通过一定的规则将词与其含义进行关联。例如,当学习外语时,我们通常会学习一些语法,包括单词的含义、单词在句子中如何排序、前缀和后缀如何改变单词的含义等。使用规则方法的前提是,可以将规则提供给NLU系统,使得NLU系统能够像人一样利用这些规则理解一句话的含义。
从20世纪50年代中期到20世纪90年代中期,基于规则的方法在NLU领域得到了广泛应用,直到机器学习方法逐渐兴起。尽管如此,基于规则的方法在某些NLU问题中依然发挥着重要的作用,无论是单独使用还是与其他方法结合使用。
接下来,我们将首先学习与自然语言相关的规则和数据。
几乎每个人都熟悉“词”这个概念,词通常被定义为可单独使用的最小语言单位。正如第1章所介绍的,在大多数语言中(并非所有),词与词之间由空格分开。由词组成的集合被称为词典,词典的概念与日常使用的字典类似,都是词的列表。NLP词典通常还包括词的其他信息,例如,词的含义和词性。根据具体的语言不同,一些词典还可能包含词的不规则形式(例如,在英语中,动词“ eat ”的过去式“ ate ”和过去分词“ eaten ”都是这个词的不规则形式)。除此之外,一些词典还包含词的语义信息,例如,与每个单词含义相关的单词。
学校教授的传统词性包括名词、动词、形容词和介词等。NLP词典使用的词性通常更详细,因为需要表达的信息要更加具体。例如,传统的英语动词具有不同的形式,如过去时、过去分词等。在NLP领域,英语常用的词性库源自Penn Treebank(https://catalog.ldc.upenn.edu/LDC99T42)。不同语言对应的NLP词典有不同的词性类别。
在处理自然语言时,标注文本中词的词性是一项非常有价值的任务,这一任务被称为 词性标注 (Part-of-Speech tagging,POS tagging)。使用Penn Treebank词性库,表3.1展示了“ We would like to book a flight from Boston to London ”这句话的词性标注结果:
表3.1 “ We would like to book a flight from Boston to London ”的词性标注结果
词性标注不仅仅是用词典查找词并标注词的词性,因为许多词不只有一个词性。在以上示例中,“ book ”这个词是动词,但是在其他地方,这个词通常为名词。所以,在使用词性标注算法标注词性时,不仅仅要看词本身,还要考虑其上下文信息,以此来确定正确的词性。在以上示例中,“ book ”在“ to ”的后面,“ to ”后面的单词通常是动词,因此“ book ”在该示例中的词性为动词。
语法或语法规则是描述词在句子中如何排列的规则,遵循语法规则的句子可以正确传达作者的意思,也很容易被读者理解。语法规则可以用来描述句子与其组成部分之间的部分整体关系。例如,一个常见的英文语法规则为:句子由名词短语与动词短语组成。任何一个NLP的语法通常都由数百条规则组成,非常复杂。在搭建NLU模型时,一般不会从零开始构建语法规则,常用的Python NLP库中都封装了常用的语法规则,如 自然语言工具包 (Natural Language ToolKit,NLTK)和 spaCy 。
确定句子各部分之间关系的过程被称为句法分析。这涉及将语法规则应用于一个具体的句子,以显示句子各组成部分是如何相互关联的。图3.1展示了“ We would like to book a flight ”这句话的句法分析结果,这种风格的句法分析被称为 依存句法分析 。在依存句法分析中,使用弧线连接表示两个词之间的关系。例如:名词“ we ”是动词“ like ”的主语,使用带有 nsubj 标签的弧线连接这两个词。
图3.1 “ We would like to book a flight ”的依存句法分析结果
本章不会过多阐述句法分析的细节,第8章将详细地介绍句法分析相关内容。
句法分析确定一个句子中各个词之间在整体结构上的关系,但并没有说明各个词之间在意思或含义上是如何相互关联的。这种基于词义的分析方式被称为 语义分析 。语义分析是一个比较活跃的研究领域,方法很多。一种常见的语义分析思路如下,从句子的谓语动词出发,观察该动词和句子其他部分之间的关系(如主语、直接宾语和相关的介词短语)。例如,图3.1中“ like ”的主语是“ We ”,“ We ”可以被描述为“ like ”的感受者,因为“ We ”是动作的发出者。同样,“ to book a flight ”可以被描述为“ like” 的对象。通常使用规则完成语义分析任务,但也可以使用机器学习算法来完成,3.2节将介绍如何使用机器学习算法进行语义分析。
摒弃掉词在句子中的角色,只寻找词之间的语义关系具有重要的意义。例如:可以把“ dog ”认为是一种“ animal ”,或者把“ eating ”认为是一种动作。Wordnet(https://wordnet.princeton.edu/)是查找这类关系的一个有用资源,它是一个人工编制的大型数据库,描述了数千个英语单词之间的关系。图3.2展示了“ airplane ”这个单词的部分Wordnet信息,首先可以得知的是“ airplane ”是一种“ heavier-than-air craft ”,更宽泛地说它是一种“ aircraft ”,以此类推,直至Wordnet最底层说“ airplane ”是一个“ entity ”。
图3.2 单词“ airplane ”的Wordnet信息
语用分析 指的是根据不同的语境确定词和短语的意思。例如:在长文本中,不同的词可能代指同一件事情,或者同一个词代指不同的事情,这种现象称为 共指 。使用语用分析方法分析句子“ We want to book a flight from Boston to London , the flight needs to leave before 10 a.m. ”,可以得知上午十点之前起飞的航班是想要预订的航班。 命名实体识别 (Named Entity Recognition,NER)是一种非常重要的语用分析方法,它可以将文本中出现的指代词与现实世界中对应的实体联系起来。图3.3展示了使用命名实体识别方法分析句子“ Book a flight to London on United for less than 1,000 dollars. ”的结果,其中“ London ”是一个命名实体,标签为地理位置(GPE),“ United ”标签为组织(ORG),“ less than 1,000 dollars ”标签为货币(MONEY)。
图3.3 “ Book a flight to London on United for less than 1,000 dollars ”的命名实体识别结果
在NLP应用程序中,以上阐述的这些任务通常使用 pipeline 实现,pipeline可看作一系列步骤的封装,其中上一个步骤的结果是下一个步骤的输入。一个经典的NLP pipeline如下:
❑ 词汇查找: 在应用程序词典中查找词。
❑ 词性标注: 根据上下文确定每个词的词性。
❑ 句法分析: 分析词之间的关系。
❑ 语义分析: 分析每个词的意思和句子的整体意思。
❑ 语用分析: 确定词和短语的具体意义,这取决于上下文,例如代词的理解方式。
使用pipeline的一个优点在于,pipeline中的每个步骤可以使用不同的方法来实现,只要上一步骤的输出符合下一步骤的输入格式即可。因此,pipeline不仅在基于规则的方法中有用,在其他方法中也有用,接下来的几节将介绍相关内容。
第8章将介绍基于规则的方法的更多细节。下面探讨一些不依赖于语言规则的方法,这些方法更侧重于机器学习。
虽然基于规则的方法可以获取语言文本的细粒度详细信息,但此类方法存在一些缺陷,也正是这些缺陷推动了替代方法的发展。基于规则的方法主要包含两个缺陷:
❑开发规则是一个费时费力的过程。规则可以由专家根据他们对语言的理解直接编写,或者更常见的方法为从一些被证实正确的文本分析或注释中总结出来。这两种方法都非常耗费时间和精力。
❑规则无法适用于系统遇到的所有文本。制定规则的专家可能会出现疏忽,注释的数据可能没有覆盖所有的情况,用户在提问时可能出现错误,这些情况都要求系统依旧工作,但此时规则未能完全覆盖系统的输入。除此之外,书写文本语言时也可能出现拼写错误,从而出现词典中没有的词。最后,语言本身也会变化,导致现有规则无法涵盖新出现的词和短语。
基于上述原因,基于规则的方法通常不单独使用,而是被用作NLU pipeline的一部分,作为其他方法的补充。
传统的机器学习方法起源于分类任务。在分类任务中,意思相似的文档会归类为同一类别。可以将分类概括为以下两个步骤:
❑组织训练数据,使相同类别训练数据中的文档相似。
❑对于模型未见过的新文档,模型会根据其与训练数据集中的文档的相似程度,对其进行分类。
文档的表示是基于词实现的。一个非常简单的方法是将文档表示为文档中词的集合,这种方法被称为 词袋法 (Bag of Words,BoW)。使用词袋法表示文档的最简单方式为使用语料库中所有词制作一个列表,然后对于每一个文档,写出列表中哪些词出现在该文档中。
例如,假设有一个语料库,这个语料库由图3.4中的三个文档组成。
图3.4 餐厅搜索的小型语料库
这个小型语料库共包含了29个英文单词。每个文档可以使用一个长度为29的列表表示该文档中出现了语料库中的哪些单词。在这个列表中,1表示单词出现,0表示单词未出现,如表3.2所示。
表3.2 餐厅搜索小型语料库每个文档的词袋表示
表3.2展示了语料库中三个文档的词袋列表,该列表仅展示了词汇表中的前八个词。表3.2中的每一行代表一个文档。例如,单词“ a ”在第一个文档中出现了一次,所以它所对应的值为1,而单词“ an ”没有出现,它所对应的值为0。在数学上这种表示是一个向量。向量在NLU领域中是一个非常好用的工具,本书后续章节将会介绍更多关于向量的内容。
词袋法看起来非常简单(例如,它没有考虑任何关于词顺序的信息),但是词袋法的一些衍生算法非常强大,相关内容将在第9章~第12章进行介绍。
词袋法的背后假设是,两个文档共用的词越多,它们在意义上就越相似。这不是一个严格的准则,但实践证明是有用的。
对于许多应用程序,我们希望将含义不相似的文档分组到不同的类别中,这个过程被称为 分类 。如果想将一个新文档分类为某个已有类别,那么需要计算这个新文档向量与每个类别文档向量的相似程度。例如,第1章中讨论的情感分析任务,该任务是将文档进行二分类,即文本的主题属于正面情绪还是负面情绪。
有多种算法可以完成文本分类任务。第9章将要介绍的 朴素贝叶斯算法 和 支持向量机(Support Vector Machine,SVM)算法 是其中最流行的两种算法。除此之外,基于神经网络的算法也非常流行,尤其是 循环神经网络 。3.3节将简要概述神经网络相关内容,更多细节将在第10章进行介绍。
本节总结了一些传统的机器学习算法。接下来介绍一些深度学习算法。
神经网络,尤其是被称为 深度学习 的大型神经网络,在过去几年里已经成为NLU领域的热门话题,因为它们显著提高了许多自然语言任务的准确率。
神经网络由多层互相连接的单元组成,这些单元被称为人工 神经元 ,类似于生物神经系统中的生物神经元。神经网络中的每个神经元都与其他神经元相连接。如果一个神经元接收到的信号超过了自身预设的阈值,那么这个神经元就会被激活,并且向其他神经元传递信号,其他神经元再根据所接收到的信号判断是否激活。在训练过程中,神经网络会不断调整每个神经元的权重,以最大化分类准确率。
图3.5展示了一个使用四层神经网络进行情感分析的示例,其中圆圈表示神经元,线段表示神经元之间的连接。网络的最左侧为第一层,用于接收输入文本。之后的两个隐藏层用于处理输入。包含一个神经元的输出层给出输出结果(正面情绪)。
图3.5 使用神经网络(四层)对产品评价进行情感分析
虽然神经网络在很多年前就已经被提出,但早期受限于计算资源和算力,神经网络发展缓慢,到了近几年训练和使用大型神经网络才逐渐成为可能。与早期算法相比,神经网络具有更高的准确率,尤其是在训练数据充足的情况下,这也是神经网络目前流行的主要原因。然而,训练一个用于大规模任务的神经网络非常复杂且耗时,并且可能还需要专业的数据科学家帮助。在某些情况下,使用神经网络所提升的系统性能与开发成本并不匹配。
关于深度学习和神经网络的更多内容将在第10章介绍。
NLU领域的最新方法基于这样一个观点,即基于通用文本(如互联网文本数据)训练的语言模型可以为理解自然语言提供所需的信息,从而为许多不同的NLU应用程序提供支持。这些模型被称为预训练模型,通常都比较大并且训练时所使用数据也比较大。在将这些预训练模型应用于某个具体应用程序时,通常需要使用该领域的数据微调模型,使模型适应应用程序数据。由于预训练模型已经包含了语言的大量通用信息,因此微调模型所使用的训练数据比传统方法使用的数据要少很多。常用的预训练模型包括BERT模型、生成式预训练Transformer(Generative Pre-trained Transformer,GPT)模型及其衍生模型。
第11章将介绍更多关于预训练模型的内容。
本章介绍了四类NLU方法,分别为:
❑基于规则的方法
❑统计机器学习方法
❑深度学习和神经网络方法
❑预训练模型
那么,当面对一个具体问题时,应该如何选择合适的解决方法?首先需要考虑的因素是一些实际问题,例如制定解决方案所需的成本、工作量等。接下来,我们对各种方法的特点进行比较。
表3.3展示了本章所介绍的四种NLU方法,并比较了它们的一些特点,包括开发人员专业知识要求、数据量要求、训练时间、准确率和成本。正如表3.3所示,每种方法都有各自的优缺点。对不需要大规模数据的小问题或简单问题而言,应首先考虑基于规则的方法、机器学习方法或预训练模型。虽然预训练模型的准确率较高且获取成本较低,但是无论是在云上还是本地计算机上,使用大模型的成本都很高,所以开发人员更倾向于避免使用预训练模型。
表3.3 比较四种NLU方法
因此在选择方法时,应该根据问题本身以及可接受的成本进行选择。除此之外,还应当注意,所选择的方法并非一直不变或不可更改,尤其是对依赖于数据标注的方法,当数据变多时可以同时使用两种或两种以上方法。
本章介绍了多种适用于NLU应用程序的方法以及一些重要的技巧。
本章首先解释了基于规则的方法的定义,以及一些常见的基于规则的方法,包括词性标注、句法分析等。然后,介绍了传统机器学习方法,特别是将文本文档转化为数字表示的方法。之后,又介绍了深度学习方法、预训练模型以及这四种方法的优缺点。
第4章将介绍NLU入门的基础知识,包括如何安装Python、如何使用JupyterLab和GitHub、如何使用NLTK和spaCy等NLU函数库,以及如何选择合适的函数库。