当前位置:首页 > 博客 > 详细信息
从“London”出发,8步搞定自然语言处理(Python代码)
发布时间:2018年09月01日 浏览次数:

来源:新智元

导读:自然语言处理是AI的一个子领域,从人们日常沟通所用的非结构化文本信息中提取结构化数据,以便计算机理解。本文用通俗易懂的语言深入浅出的介绍了自然语言处理,并用Python实现了几个非常有趣的实例。

自然语言处理(NLP)是人工智能的一个子领域,它专注于使计算机能够理解和处理人类语言。本文会介绍NLP工作的基本机制,希望读者能从中得到启发。

计算机能理解语言吗?

自计算机诞生之初,程序员们就一直在尝试编写能理解语言的程序。原因很简单——人类使用语言的历史已长达千年,如果计算机能阅读并理解所有数据,这将大有裨益。

虽然现在计算机还不能像人类一样真正读懂语言,但它们确实取得了不少进展,在某些领域,使用NLP可以为事物带来神奇的改变。通过把NLP技术应用于你自己的项目,也许你会因此节约大量时间。

更好的消息是,现在我们可以通过开源Python库(如spaCy、textacy和neuralcoref)轻松访问NLP领域的最新成果。只需几行代码,令人惊叹的成果立马实现。

从文本中提取意义很难

阅读和理解语言是一个非常复杂的过程——它们甚至不会判断这样的理解是否符合逻辑和一致性。例如,下面这个新闻标题表达了什么含义?

“Environmental regulators grill business owner over illegal coal fires.” 环境监管机构就非法燃煤一事___企业主。(grill:追问,炙烤)

监管机构是在质疑企业存在非法燃煤情况,还是在拿企业主做饭?如你所见,用计算机解析语言会让问题变得很复杂。

在机器学习中,解决复杂任务通常意味着建立一个pipeline。它的想法是把问题分解成若干个非常小的部分,然后用机器学习去一一破解,最后,通过将这些机器学习模型拼接在一起,我们可以用它完成复杂任务。

而这正是我们在NLP中常用的策略。我们把理解语言文本这个过程分成几个小块,然后独立推敲它们的具体理解方式。

逐步构建NLP Pipeline

下面是维基百科中关于“伦敦”的一段文字:

London is the capital and most populous city of England and the United Kingdom. Standing on the River Thames in the south east of the island of Great Britain, London has been a major settlement for two millennia. It was founded by the Romans, who named it Londinium. 伦敦是英格兰和英国的首府,也是英国人口最多的城市。它位于大不列颠岛东南部的泰晤士河畔,2000年来一直是这一地区的主要定居点之一。伦敦最初由罗马人建立,取名为伦蒂尼恩。

这段文字包含多个有用事实,如果计算机能从中读懂“伦敦是一座城市”“伦敦位于英格兰”“伦敦由罗马人建立”,那就大功告成了。但为了实现这一目标,我们首先要向计算机传授书面语言的最基本概念,然后再谋求进一步发展。

第一步:语句分割(Sentence Segmentation

NLP pipeline的第一步是先把文本分割成单独的句子,如下所示:

1.  伦敦是英格兰和英国的首府,也是英国人口最多的城市。

2.  它位于大不列颠岛东南部的泰晤士河畔,2000年来一直是这一地区主要的定居点之一。

3.  伦敦最初由罗马人建立,取名为伦蒂尼恩。

我们可以假设这里的每个句子都表示一种独立的思想或想法,比起理解整个段落,编写程序来理解单个句子确实会容易得多。

至于构建语句分割模型,这不是一件难事,我们可以根据标点符号确定每个句子。当然,现代NLP通常会用更复杂的技术,即便文档内容不整洁,它还是能大致区分完整句子。

第二步:单词词例(Word Tokenization

有了一个个被拆分的句子,现在我们可以对它们进行逐一处理。让我们从第一句开始:

London is the capital and most populous city of England and the United Kingdom.

这一步的目标是把句子再分割成单独的单词或标点符号,分割完成后,整个句子变成了这样:

“London”, “is”, “ the”, “capital”, “and”, “most”, “populous”, “city”, “of”, “England”, “and”, “the”, “United”, “Kingdom”, “.”

英语中存在自然分界符——空格,所以对它生成词例非常方便。只要两个词例之间有空格,我们就可以把它们直接分开。因为标点符号也有意义,我们要把它们视为单独的词例。

第三步:预测词例词性

接下来,我们来关注词例的词性:名词、动词、形容词……知道每个词语在句子中的作用有助于我们理解句子在说什么。

要实现这一点,我们可以事先训练一个词性分类模型,然后把每个单词输入其中预测词性:

这个模型最初是在数百万个英语句子上训练的,数据集中已经标明每个单词的词性,因此它可以学会这个“定义”的过程。但是注意一点,这个模型完全是基于统计数据的——它实际上无法像人类那样理解单词含义,而是只能根据“看”到过的类似句子进行猜测。

处理完整句后,我们会得到这样的结果:

有了这些信息,我们就可以开始收集一些非常基本的含义,比如句子中的名词包括“伦敦”“首府”,所以这句话有大概率是在谈论伦敦。

第四步:文本词形还原(Text Lemmatization

在英语中,单词是有不同形式的,比如:

  1. I had a pony.
  2. I had two ponies.

两个句子都涉及名词pony(小马),但一个是单数形式,一个是复数形式。当计算机在处理文本时,如果没有说明,它会把“pony”和“ponies”看成完全不同的对象,因此了解每个单词的基本形式很有帮助,只有这样,计算机才知道两个句子在谈论同一个概念。

在NLP中,我们把这种将一个任何形式的语言词汇还原为一般形式的过程称为词形还原,它能找出句子中每个单词的最基本形式。

同样的,这也适用于英语动词。我们可以用词形还原找出单词词根,这之后,“I had two ponies”就变成了“I [have] two [pony]”。

词形还原是通过检索词汇生成表格实现的,它也有可能具有一些自定义规则,可以处理人们从未见过的单词。

以下是经还原的例句,我们做的唯一改变是把“is”变成“be”:

第五步:识别停用词(Identifying Stop Words

然后就是衡量句子中每个单词的重要性。英语中有很多填充词,比如经常出现的“and”“the”和“a”。在对文本进行统计时,这些词会引入很多噪音,因为它们出现的频率很高。一些NLP pipeline会将它们标记为停用词 ——也就是说,在进行任何统计分析之前,我们可能会希望过滤掉这些词。

下面是标灰停用词的例句:

停用词检测也有一个事先准备好的列表,但它和词形还原有区别,我们没有适用于任何问题的标准停用词列表,它需要具体问题具体分析。比方说,如果我们要构建一个有关摇滚乐队的搜索引擎,那“The”这个词千万不能被忽略,因为它会出现在很多乐队的名字里,20世纪80年代还有一支著名的乐队叫“The The”。

第六步(a):依存句法分析(Dependency Parsing

下一步是弄清楚句子中的所有单词是如何相互关联的,也就是依存句法分析。

我们的目标是构建一棵依存树,其中树根处是占据支配地位的主要动词,简称主词,处于依存地位的是从词:

但我们可以更进一步。除了识别每个单词的主词外,我们还可以预测这两个单词之间的依存关系类型:

这棵依存树告诉我们句子的主语是“London”,它和“capital”存在一个“be”的关系。据此我们得到了一条有用信息——London is a capital。在这个基础上,如果我们继续往后看,可以发现,其实London is the capital of the United Kingdom。

就像我们之前使用机器学习模型预测词性一样,依存句法分析也可以用一个模型来实现。不同的是,解析单词依存特别复杂,需要结合整篇文章详细解释。如果你感兴趣,Matthew Honnibal的“用500行Python代码解析英语”是个不错的教程。

虽然2015年的时候,作者表示这种方法已经成为标准,但放到现在来看,它还是有点过时,很多研究人员都已经不再用它了。2016年,Google发布了一个名为Parsey McParseface的新依存解析器,它基于深度学习,在性能上明显超出已有基准,因此一经发布就被广泛传播。一年后,他们又发布了更新版本ParseySaurus,进一步做了提升。简而言之,依存句法分析现在还是一个活跃的研究领域,并且在不断变化和改进。

此外,许多英语句子存在意义含糊不清的问题,往往难以解析。在这些情况下,模型会基于句子的各个解析版本猜测一个可能性最高的选择,但它并不完美,有时模型会出现令人尴尬的错误。但随着时间的推移,我们的NLP模型会逐渐走向合理。

第六步(b):寻找名词短语

到目前为止,我们已经把句子中的每个单词视为一个单独的实体,但有时这些表示单个想法或事物的词组合在一起会更有意义。利用依存树,我们可以自动整合信息,把讨论同一个事物的单词组合在一起。

比起下图这个形式:

我们可以对名词短语进行分组以生成:

是否要采取这一步骤取决于我们的最终目标。但是,如果我们不需要了解句子的额外细节,比如哪些词是形容词,而是更多地关注提取完整想法,那么这通常是简化句子的一个便捷方法。

第七步:命名实体识别(NER

完成上述步骤后,我们就可以摆脱初级语法,开始真正着手提取意义。

在示例句子中,我们有以下名词:

这些名词中包含一些现实存在的东西,比如“伦敦”“英格兰”“英国”表示地图上的某个地理位置。有了这些信息,我们就可以使用NLP自动提取文档中提到的真实世界的位置列表。

命名实体识别(NER)的目标是检测这些表示现实世界食物的词,并对它们进行标记。下图把各个词例输入NER模型后,示例句子的变化情况:

虽然直观上看不出,但NER绝不是简单地查词典、打标签,它包含一个单词在上下文中位置的统计模型,可以预测不同单词分别代表哪种类型的名词。举个例子,一个好的NER模型可以区分“Brooklyn”是表示人名Brooklyn Decker,还是地名布鲁克林。

以下是典型NER系统可以标记的一些对象:

  • 人的名字
  • 公司名称
  • 地理位置(地缘和政治)
  • 产品名称
  • 日期和时间
  • 金额
  • 事件名称

NER有很多用途,因为它可以轻易从文本中获取结构化数据,这是快速从NLP pipeline中获取有价值信息的最简单的方法之一。

第八步:共指消解

截至目前,我们已经有了许多和句子相关的有用表征。我们知道每个单词的词性、单词间的依存关系,以及那些词表示命名实体。

但我们还有一个棘手的问题,就是英语中包含大量代词,比如“he”“she”“it”,这些词频繁出现在句子里,是我们为了避免重复提及某个名称而使用的简称。人类可以根据上下文理解这些代词的含义,但NLP模型不行,因为到目前为止,它只是一句一句地检测。

让我们来看示例的第三句:

“It was founded by the Romans, who named it Londinium.

根据NLP pipeline,我们的模型只知道“it”是罗马人造的,还不知道“it”是什么。但这个问题想必难不倒任何读得动这段话的人,我们知道这里的“it”就是第一句里的“London”。

以下是在我们的文档中为“伦敦”一词运行共识解析的结果:

通过将共指消解与依存树、命名实体信息相结合,我们可以从该文档中提取大量信息!事实上,这也是现在NLP领域的一大难点,它的难度远高于单个句子解析。虽然近年来基于深度学习最新进展的某些成果已经取得了一定突破,但它们都不完美。

以上是关于NLP的一些基础知识,如果你对这个内容感兴趣,以后我们还会讨论NLP的更多内容,如文本分类、智能助理解析问题等具体应用。

分享到:
爱客服服务热线:400-005-0025 官方邮箱:aikf@huilan.com
© 2015-2017 北京中科汇联科技股份有限公司版权所有 京ICP备05046823
点我咨询