对于任何给定的问题,很可能已经有人把答案写在某个地方了。以电子形式提供的自然语言文本的数量真的惊人,并且与日俱增。然而,自然语言的复杂性使访问这些文本中的信息非常困难。NLP目前的技术水平仍然有很长的路要走才能够从不受限制的文本对意义建立通用的表示。如果我们不是集中我们的精力在问题或“实体关系”的有限集合,例如:“不同的设施位于何处”或“谁被什么公司雇用”上,我们就能取得重大进展。本章的目的是要回答下列问题:
一路上,我们将应用前面两章中的技术来解决分块和命名实体识别。
信息有很多种形状和大小。一个重要的形式是结构化数据:实体和关系的可预测的规范的结构。例如,我们可能对公司和地点之间的关系感兴趣。给定一个公司,我们希望能够确定它做业务的位置;反过来,给定位置,我们会想发现哪些公司在该位置做业务。如果我们的数据是表格形式,如1.1中的例子,那么回答这些问题就很简单了。
位置数据
机构名 | 位置名 |
---|---|
Omnicom | 纽约 |
DDB Needham | 纽约 |
Kaplan Thaler Group | 纽约 |
BBDO South | 亚特兰大 |
Georgia-Pacific | 亚特兰大 |
如果这个位置数据被作为一个元组(entity, relation, entity)的列表存储在Python中,那么这个问题:“哪些组织在亚特兰大经营?”可翻译如下:
|
在亚特兰大运营的公司
机构名 |
---|
BBDO South |
Georgia-Pacific |
如果我们尝试从文本中获得相似的信息,事情就比较麻烦了。例如,思考下面的片段(来自nltk.corpus.ieer,fileid为NYT19980315.0085)。
(1) | The fourth Wells account moving to another agency is the packaged paper-products division of Georgia-Pacific Corp., which arrived at Wells only last fall. Like Hertz and the History Channel, it is also leaving for an Omnicom-owned agency, the BBDO South unit of BBDO Worldwide. BBDO South in Atlanta, which handles corporate advertising for Georgia-Pacific, will assume additional duties for brands like Angel Soft toilet tissue and Sparkle paper towels, said Ken Haldin, a spokesman for Georgia-Pacific in Atlanta. |
如果你通读了(1),你将收集到回答例子问题所需的信息。但我们如何能让一台机器理解(1)来返回1.2中的答案呢?这显然是一个困难得多的任务。与1.1不同,(1)不包含连结组织名和位置名的结构。
这个问题的解决方法之一是对意义建立一个非常通用的表示(10.)。在这一章中,我们采取不同的方法,事先确定我们将只查找文本中非常具体的各种信息,如组织和地点之间的关系。不是试图用像(1)那样的文字直接回答这个问题,我们首先将自然语言句子的非结构化数据转换成1.1这样的结构化数据。然后,利用强大的查询工具,如SQL。这种从文本获取意义的方法被称为信息提取。
信息提取有许多应用,包括商业智能、简历收获、媒体分析、情感检测、专利检索、电子邮件扫描。当前研究的一个特别重要的领域是提取出电子科学文献的结构化数据,特别是在生物学和医学领域。
1.1显示一个简单的信息提取系统的架构。它开始于使用3和5.中讨论过的几个程序处理文档:首先,使用句子分割器将该文档的原始文本分割成句,使用分词器将每个句子进一步细分为词。接下来,对每个句子进行词性标注,在下一步命名实体识别中将证明这是非常有益的。在这一步,我们寻找每个句子中提到的有潜在价值的实体。最后,我们使用关系识别搜索文本中不同实体间的可能关系。
要执行前面三项任务,我们可以定义一个简单的函数,简单地连接NLTK中默认的句子分割器,分词器和词性标注器:
注意
请记住我们的例子程序假设你以import nltk, re, pprint开始交互式会话或程序。
接下来,命名实体识别中,我们分割和标注可能组成一个有趣关系的实体。通常情况下,这些将被定义为名词短语,例如the knights who say "ni"或者适当的名称如Monty Python。在一些任务中,同时考虑不明确的名词或名词块也是有用的,如every student或cats,这些不必要一定与确定的NPs和适当名称一样的方式指示实体。
最后,在提取关系时,我们搜索对文本中出现在附近的实体对之间的特殊模式,并使用这些模式建立元组记录实体之间的关系。
我们将用于实体识别的基本技术是词块划分,它分割和标注多词符的序列,如2.1所示。小框显示词级分词和词性标注,大框显示高级别的词块划分。每个这种较大的框叫做一个词块。就像分词忽略空白符,词块划分通常选择词符的一个子集。同样像分词一样,词块划分器生成的片段在源文本中不能重叠。
在本节中,我们将在较深的层面探讨词块划分,以词块的定义和表示开始。我们将看到正则表达式和N-gram的方法来词块划分,使用CoNLL-2000词块划分语料库开发和评估词块划分器。我们将在(5)和6回到命名实体识别和关系抽取的任务。
我们将首先思考名词短语词块划分或NP词块划分任务,在那里我们寻找单独名词短语对应的词块。例如,这里是一些《华尔街日报》文本,其中的NP词块用方括号标记:
(2) | [ The/DT market/NN ] for/IN [ system-management/NN software/NN ] for/IN [ Digital/NNP ] [ 's/POS hardware/NN ] is/VBZ fragmented/JJ enough/RB that/IN [ a/DT giant/NN ] such/JJ as/IN [ Computer/NNP Associates/NNPS ] should/MD do/VB well/RB there/RB ./. |
正如我们可以看到,NP词块往往是比完整的名词短语稍小的片段。例如,the market for system-management software for Digital's hardware是一个单独的名词短语(包含两个嵌套的名词短语),但是它被更简单的词块the market分割为NP词块。这种差异的动机之一是NP词块被定义为不包含其他的NP词块。因此,修饰一个名词的任何介词短语或从句将不包括在相应的NP词块内,因为它们几乎可以肯定包含更多的名词短语。
NP词块信息最有用的来源之一是词性标记。这是在我们的信息提取系统中进行词性标注的动机之一。我们在2.2中用一个已经标注词性的例句来演示这种方法。为了创建一个NP词块划分器,我们将首先定义一个词块语法,由指示句子应如何进行词块划分的规则组成。在本例中,我们将用一个正则表达式规则定义一个简单的语法。这条规则说,每当词块划分器发现一个可选的限定词(DT)后面跟着任何数目的形容词(JJ)然后是一个名词(NN)就应该组成一个NP词块。使用此语法,我们创建了一个词块解析器,并在我们的例句上测试。结果是一棵树,我们可以打印或图形显示。
| ||
组成一个词块语法的规则使用标记模式来描述已标注的词的序列。一个标记模式是一个词性标记序列,用尖括号分隔,如<DT>?<JJ>*<NN>。标记模式类似于正则表达式模式(3.4)。现在,思考下面的来自《华尔街日报》的名词短语:
another/DT sharp/JJ dive/NN trade/NN figures/NNS any/DT new/JJ policy/NN measures/NNS earlier/JJR stages/NNS Panamanian/JJ dictator/NN Manuel/NNP Noriega/NNP
我们可以使用轻微改进的上述第一个标记模式来匹配这些名词短语,如<DT>?<JJ.*>*<NN.*>+。这将词块划分任何以一个可选的限定词开头,后面跟零个或多个任何类型的形容词(包括相对形容词,如earlier/JJR),后面跟一个或多个任何类型的名词的标识符序列。然而,很容易找到许多该规则不包括的更复杂的例子:
his/PRP$ Mansion/NNP House/NNP speech/NN the/DT price/NN cutting/VBG 3/CD %/NN to/TO 4/CD %/NN more/JJR than/IN 10/CD %/NN the/DT fastest/JJS developing/VBG trends/NNS 's/POS skill/NN
注意
轮到你来:尝试用标记模式覆盖这些案例。使用图形界面nltk.app.chunkparser()测试它们。使用此工具提供的帮助资料继续完善你的标记模式。
要找到一个给定的句子的词块结构,RegexpParser词块划分器以一个没有词符被划分的平面结构开始。词块划分规则轮流应用,依次更新词块结构。一旦所有的规则都被调用,返回生成的词块结构。
2.3显示了一个由2个规则组成的简单的词块语法。第一条规则匹配一个可选的限定词或所有格代名词,零个或多个形容词,然后跟一个名词。第二条规则匹配一个或多个专有名词。我们还定义了一个进行词块划分的例句,并在此输入上运行这个词块划分器。
| ||
| ||
注意
$符号是正则表达式中的一个特殊字符,必须使用反斜杠转义来匹配PP$标记。
如果标记模式匹配位置重叠,最左边的匹配优先。例如,如果我们应用一个匹配两个连续的名词文本的规则到一个包含三个连续的名词的文本,则只有前两个名词将被划分:
|
一旦我们创建了money market词块,我们就已经消除了允许fund被包含在一个词块中的上下文。这个问题可以避免,使用一种更加宽容的块规则,如NP: {<NN>+}。
注意
我们已经为每个块规则添加了一个注释。这些是可选的;当它们的存在时,词块划分器将它作为其跟踪输出的一部分输出这些注释。
在2中,我们看到了我们如何在已标注的语料库中提取匹配的特定的词性标记序列的短语。我们可以使用词块划分器更容易的做同样的工作,如下:
|
注意
轮到你来:将上面的例子封装在函数find_chunks()内,以一个如"CHUNK: {<V.*> <TO> <V.*>}"的词块字符串作为参数。Use it to search the corpus for several other patterns, such as four or more nouns in a row, e.g. "NOUNS: {<N.*>{4,}}"
有时定义我们想从一个词块中排除什么比较容易。我们可以定义词缝为一个不包含在词块中的一个词符序列。在下面的例子中,barked/VBD at/IN是一个词缝:
[ the/DT little/JJ yellow/JJ dog/NN ] barked/VBD at/IN [ the/DT cat/NN ]
词缝加塞是从词块中去除一个词符序列的过程。如果匹配的词符序列贯穿一个完整的词块,那么这个完整的词块会被去除;如果词符序列出现在词块中间,这些词符会被去除,在以前只有一个词块的地方留下两个词块。如果序列在词块的两侧,这些词符被去除,一个更小的词块会留下。这三种可能性在2.1中予以说明。
三个词缝加塞规则应用到相同的词块
` ` | 完整的词块 | 词块的中间 | 词块的尾部 |
---|---|---|---|
输入 | [a/DT little/JJ dog/NN] | [a/DT little/JJ dog/NN] | [a/DT little/JJ dog/NN] |
操作 | Chink "DT JJ NN" | Chink "JJ" | Chink "NN" |
模式 | }DT JJ NN{ | }JJ{ | }NN{ |
输出 | a/DT little/JJ dog/NN | [a/DT] little/JJ [dog/NN] | [a/DT little/JJ] dog/NN |
在2.4中,我们将完整的句子放入到一个单独的词块中,然后切除词缝。
| ||
| ||
作为标注和分析之间的中间状态(8.,词块结构可以使用标记或树来表示。最广泛的文件表示使用IOB标记。在这个方案中,每个词符被三个特殊的词块标记之一标注,I(内部),O(外部)或B(开始)。一个词符被标注为B,如果它标志着一个词块的开始。块内的词符子序列被标注为I。所有其他的词符被标注为O。B和I标记后面跟着词块类型,如B-NP, I-NP。当然,没有必要指定出现在词块外的词符类型,所以这些都只标注为O。这个方案的例子如2.5所示。
IOB标记已成为文件中表示词块结构的标准方式,我们也将使用这种格式。下面是2.5中的信息如何出现在一个文件中的:
We PRP B-NP saw VBD O the DT B-NP yellow JJ I-NP dog NN I-NP
在此表示中,每个词符一行,和它的词性标记与词块标记一起。这种格式允许我们表示多个词块类型,只要词块不重叠。正如我们前面所看到的,词块的结构也可以使用树表示。这有利于使每个词块作为一个组成部分可以直接操作。一个例子如2.6所示。
注意
NLTK使用树作为词块的内部表示,并提供这些树与IOB格式互换的方法。
现在你对分块的作用有了一些了解,但我们并没有解释如何评估词块划分器。和往常一样,这需要一个合适的已标注语料库。我们一开始寻找将IOB格式转换成NLTK树的机制,然后是使用已化分词块的语料库如何在一个更大的规模上做这个。我们将看到如何为一个词块划分器相对一个语料库的准确性打分,再看看一些数据驱动方式搜索NP词块。我们整个的重点在于扩展一个词块划分器的覆盖范围。
使用corpus模块,我们可以加载已经标注并使用IOB符号划分词块的《华尔街日报》文本。这个语料库提供的词块类型有NP,VP和PP。正如我们已经看到的,每个句子使用多行表示,如下所示:
he PRP B-NP accepted VBD B-VP the DT B-NP position NN I-NP ...
转换函数chunk.conllstr2tree()从这些多行字符串建立一个树表示。此外,它允许我们选择使用三个词块类型的任何子集,这里只是NP词块:
|
我们可以使用NLTK的corpus模块访问较大量的已经划分词块的文本。CoNLL2000语料库包含27万词的《华尔街日报文本》,分为“训练”和“测试”两部分,标注有词性标记和IOB格式词块标记。我们可以使用nltk.corpus.conll2000访问这些数据。下面是一个读取语料库的“训练”部分的第100个句子的例子:
|
正如你看到的,CoNLL2000语料库包含三种词块类型:NP词块,我们已经看到了;VP词块如has already delivered;PP块如because of。因为现在我们唯一感兴趣的是NP词块,我们可以使用chunk_types参数选择它们:
|
现在,我们可以访问一个已划分词块语料,可以评估词块划分器。我们开始为没有什么意义的词块解析器cp建立一个基准,它不划分任何词块:
|
IOB标记准确性表明超过三分之一的词被标注为O,即没有在NP词块中。然而,由于我们的标注器没有找到任何词块,其精度、召回率和F-度量均为零。现在让我们尝试一个初级的正则表达式词块划分器,查找以名词短语标记的特征字母开头的标记(如CD, DT和JJ)。
|
正如你看到的,这种方法达到相当好的结果。但是,我们可以采用更多数据驱动的方法改善它,在这里我们使用训练语料找到对每个词性标记最有可能的块标记(I, O或B)。换句话说,我们可以使用一元标注器(4)建立一个词块划分器。但不是尝试确定每个词的正确的词性标记,而是根据每个词的词性标记,尝试确定正确的词块标记。
在3.1中,我们定义了UnigramChunker类,使用一元标注器给句子加词块标记。这个类的大部分代码只是用来在NLTK 的ChunkParserI接口使用的词块树表示和嵌入式标注器使用的IOB表示之间镜像转换。类定义了两个方法:一个构造函数,当我们建立一个新的UnigramChunker时调用;以及parse方法,用来给新句子划分词块。
| ||
构造函数需要训练句子的一个列表,这将是词块树的形式。它首先将训练数据转换成适合训练标注器的形式,使用tree2conlltags映射每个词块树到一个word,tag,chunk三元组的列表。然后使用转换好的训练数据训练一个一元标注器,并存储在self.tagger供以后使用。
parse方法接收一个已标注的句子作为其输入,以从那句话提取词性标记开始。它然后使用在构造函数中训练过的标注器self.tagger,为词性标记标注IOB词块标记。接下来,它提取词块标记,与原句组合,产生conlltags。最后,它使用conlltags2tree将结果转换成一个词块树。
现在我们有了UnigramChunker,可以使用CoNLL2000语料库训练它,并测试其表现:
|
这个分块器相当不错,达到整体F-度量83%的得分。让我们来看一看通过使用一元标注器分配一个标记给每个语料库中出现的词性标记,它学到了什么:
|
它已经发现大多数标点符号出现在NP词块外,除了两种货币符号#和$。它也发现限定词(DT)和所有格(PRP$和WP$)出现在NP词块的开头,而名词类型(NN, NNP, NNPS,NNS)大多出现在NP词块内。
建立了一个一元分块器,很容易建立一个二元分块器:我们只需要改变类的名称为BigramChunker,修改3.1行构造一个BigramTagger而不是UnigramTagger。由此产生的词块划分器的性能略高于一元词块划分器:
|
无论是基于正则表达式的词块划分器还是n-gram词块划分器,决定创建什么词块完全基于词性标记。然而,有时词性标记不足以确定一个句子应如何划分词块。例如,考虑下面的两个语句:
(3) |
|
这两句话的词性标记相同,但词块划分方式不同。在第一句中,the farmer和rice都是单独的词块,而在第二个句子中相应的部分,the computer monitor,是一个单独的词块。显然,如果我们想最大限度地提升词块划分的准确性,我们需要使用词的内容信息,作为词性标记的补充。
我们包含词的内容信息的方法之一是使用基于分类器的标注器对句子划分词块。如在上一节使用的n-gram词块划分器,这个基于分类器的词块划分器分配IOB标记给句子中的词,然后将这些标记转换为词块。对于基于分类器的标注器本身,我们将使用与我们在1中建立词性标注器相同的方法。
基于分类器的NP词块划分器的基本代码如3.2所示。它包括两个类。第一个类几乎与1.5中ConsecutivePosTagger类相同。仅有的两个区别是它调用一个不同的特征提取器,和它使用MaxentClassifier而不是NaiveBayesClassifier。第二个类基本上是标注器类的一个包装器,将它变成一个词块划分器。训练期间,这第二个类映射训练语料中的词块树到标记序列;在parse() 方法中,它将标注器提供的标记序列转换回一个词块树。
| ||
留下来唯一需要填写的是特征提取器。首先,我们定义一个简单的特征提取器,它只是提供了当前词符的词性标记。使用此特征提取器,我们的基于分类器的词块划分器的表现与一元词块划分器非常类似:
|
我们还可以添加一个特征表示前面词的词性标记。添加此特征允许词块划分器模拟相邻标记之间的相互作用,由此产生的词块划分器与二元词块划分器非常接近。
|
下一步,我们将尝试为当前词增加特征,因为我们假设这个词的内容应该对词块划有用。我们发现这个特征确实提高了词块划分器的表现,大约1.5个百分点(相应的错误率减少大约10%)。
|
最后,我们尝试用多种附加特征扩展特征提取器,例如预取特征、配对特征和复杂的语境特征。这最后一个特征,称为tags-since-dt,创建一个字符串,描述自最近的限定词以来遇到的所有词性标记,或如果没有限定词则在索引i之前自语句开始以来遇到的所有词性标记。
|
|
|
注意
轮到你来:尝试为特征提取器函数npchunk_features增加不同的特征,看看是否可以进一步改善NP词块划分器的表现。
到目前为止,我们的词块结构一直是相对平的。已标注词符组成的树在如NP这样的词块节点下任意组合。然而,只需创建一个包含递归规则的多级的词块语法,就可以建立任意深度的词块结构。4.1是名词短语、介词短语、动词短语和句子的模式。这是一个四级词块语法器,可以用来创建深度最多为4的结构。
| ||
| ||
不幸的是,这一结果丢掉了saw为首的VP。它还有其他缺陷。当我们将此词块划分器应用到一个有更深嵌套的句子时,让我们看看会发生什么。请注意,它无法识别开始的VP词块。
|
这些问题的解决方案是让词块划分器在它的模式中循环:尝试完所有模式之后,重复此过程。我们添加一个可选的第二个参数loop指定这套模式应该循环的次数:
|
注意
这个级联过程使我们能创建深层结构。然而,创建和调试级联过程是困难的,关键点是它能更有效地做全面的分析(见第8.章)。另外,级联过程只能产生固定深度的树(不超过级联级数),完整的句法分析这是不够的。
tree是一组连接的加标签节点,从一个特殊的根节点沿一条唯一的路径到达每个节点。下面是一棵树的例子(注意它们标准的画法是颠倒的):
(4) |
我们用“家庭”来比喻树中节点的关系:例如,S是VP的父母;反之VP是S 的一个孩子。此外,由于NP和VP同为S的两个孩子,它们也是兄弟。为方便起见,也有特定树的文本格式:
|
虽然我们将只集中关注语法树,树可以用来编码任何同构的超越语言形式序列的层次结构(如形态结构、篇章结构)。一般情况下,叶子和节点值不一定要是字符串。
在NLTK中,我们通过给一个节点添加标签和一系列的孩子创建一棵树:
|
我们可以将这些不断合并成更大的树,如下所示:
|
下面是树对象的一些的方法:
|
复杂的树用括号表示难以阅读。在这些情况下,draw方法是非常有用的。它会打开一个新窗口,包含树的一个图形表示。树显示窗口可以放大和缩小,子树可以折叠和展开,并将图形表示输出为一个postscript文件(包含在一个文档中)。
|
使用递归函数来遍历树是标准的做法。4.2中的内容进行了演示。
| ||
注意
我们已经使用了一种叫做动态类型的技术,检测t是一棵树(如定义了t.label())。
在本章开头,我们简要介绍了命名实体(NE)。命名实体是确切的名词短语,指示特定类型的个体,如组织、人、日期等。5.1列出了一些较常用的NE类型。这些应该是不言自明的,除了“FACILITY”:建筑和土木工程领域的人造产品;以及“GPE”:地缘政治实体,如城市、州/省、国家。
常用命名实体类型
NE类型 | 示例 |
---|---|
组织 | Georgia-Pacific Corp., WHO |
人 | Eddy Bonte, President Obama |
地点 | Murray River, Mount Everest |
日期 | June, 2008-06-29 |
时间 | two fifty a m, 1:30 p.m. |
货币 | 175 million Canadian Dollars, GBP 10.40 |
百分数 | twenty pct, 18.75 % |
设施 | Washington Monument, Stonehenge |
地缘政治实体 | South East Asia, Midlothian |
命名实体识别(NER)系统的目标是识别文字提及的所有命名实体。可以分解成两个子任务:确定NE的边界和确定其类型。命名实体识别经常是信息提取中关系识别的前奏,它也有助于其他任务。例如,在问答系统(QA)中,我们试图提高信息检索的精确度,不是返回整个页面而只是包含用户问题的答案的那些部分。大多数QA系统利用标准信息检索返回的文件,然后尝试分离文档中包含答案的最小的文本片段。现在假设问题是Who was the first President of the US?,被检索的一个文档中包含下面这段话:
(5) | The Washington Monument is the most prominent structure in Washington, D.C. and one of the city's early attractions. It was built in honor of George Washington, who led the country to independence and then became its first President. |
分析问题时我们想到答案应该是X was the first President of the US的形式,其中X不仅是一个名词短语,也是一个PERSON类型的命名实体。这应该使我们忽略段落中的第一句话。虽然它包含Washington的两个出现,命名实体识别应该告诉我们它们都不是正确的类型。
我们如何识别命名实体呢?一个办法是查找一个适当的名称列表。例如,识别地点时,我们可以使用地名辞典,或地理词典,如亚历山大地名辞典或盖蒂地名辞典。然而,盲目这样做会出问题,如5.1所示。
可以观察到,地名辞典很好的覆盖了很多国家的地点,却错误地认为Sanchez在多米尼加共和国而On在越南。当然,我们可以从地名辞典中忽略这些地名,但这样一来当它们出现在一个文档中时,我们将无法识别它们。
人或组织的名称的情况更加困难。任何这些名称的列表都肯定覆盖不全。每天都有新的组织出现,如果我们正在努力处理当代文本或博客条目,使用名称辞典查找来识别众多实体是不可能的。
困难的另一个原因是许多命名实体措辞有歧义。May和North可能分别是日期和地点类型的命名实体的,但也可以都是人名;相反的,Christian Dior看上去像是一个人名,但更可能是组织类型。词Yankee在某些上下文中是普通的修饰语,但在短语Yankee infielders中会被标注为组织类型的一个实体。
更大的挑战来自如Stanford University这样的多词名称和包含其他名称的名称,如Cecil H. Green Library和Escondido Village Conference Service Center。因此,在命名实体识别中,我们需要能够识别多词符序列的开头和结尾。
命名实体识别是一个非常适合用基于分类器类型的方法来处理的任务,这些方法我们在名词短语词块划分时看到过。特别是,我们可以建立一个标注器,为使用IOB格式的每个词块都加了适当类型标签的句子中的每个词加标签。这里是CONLL 2002(conll2002)荷兰语训练数据的一部分:
Eddy N B-PER Bonte N I-PER is V O woordvoerder N O van Prep O diezelfde Pron O Hogeschool N B-ORG . Punc O
在上面的表示中,每个词符一行,与它的词性标记及命名实体标记一起。基于这个训练语料,我们可以构造一个可以用来标注新句子的标注器;使用nltk.chunk.conlltags2tree()函数将标记序列转换成一个词块树。
NLTK提供了一个已经训练好的可以识别命名实体的分类器,使用函数nltk.ne_chunk()访问。如果我们设置参数binary=True,那么命名实体只被标注为NE;否则,分类器会添加类型标签,如PERSON, ORGANIZATION和 GPE。
|
|
一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。如前所述,我们通常会寻找指定类型的命名实体之间的关系。进行这一任务的方法之一是首先寻找所有X, α, Y)形式的三元组,其中X和Y是指定类型的命名实体,α表示X和Y之间关系的字符串。然后我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词in的字符串。特殊的正则表达式(?!\b.+ing\b)是一个否定预测先行断言,允许我们忽略如success in supervising the transition of中的字符串,其中in后面跟一个动名词。
|
搜索关键字in执行的相当不错,虽然它的检索结果也会误报,例如[ORG: House Transportation Committee] , secured the most money in the [LOC: New York];一种简单的基于字符串的方法排除这样的填充字符串似乎不太可能。
如前文所示,conll2002命名实体语料库的荷兰语部分不只包含命名实体标注,也包含词性标注。这允许我们设计对这些标记敏感的模式,如下面的例子所示。clause()方法以分条形式输出关系,其中二元关系符号作为参数relsym的值被指定。
|
本章的附加材料发布在http://nltk.org/,包括网络上免费提供的资源的链接。关于使用NLTK词块划分的更多的例子,请看在http://nltk.org/howto上的词块划分HOWTO。
分块的普及很大一部分是由于Abney的开创性的工作,如(Church, Young, & Bloothooft, 1996)。http://www.vinartus.net/spa/97a.pdf中描述了Abney的Cass词块划分器器。
根据Ross和Tukey在1975年的论文(Church, Young, & Bloothooft, 1996),单词词缝最初的意思是一个停用词序列。
IOB格式(有时也称为BIO格式)由(Ramshaw & Marcus, 1995)开发用来NP划分词块,并被由Conference on Natural Language Learning在1999年用于NP加括号共享任务。CoNLL 2000采用相同的格式标注了华尔街日报的文本作为一个NP词块划分共享任务的一部分。
(Jurafsky & Martin, 2008)的13.5节包含有关词块划分的一个讨论。第22 章讲述信息提取,包括命名实体识别。有关生物学和医学中的文本挖掘的信息,请参阅(Ananiadou & McNaught, 2006)。
关于本文档...
针对NLTK 3.0 作出更新。本章来自于Natural Language Processing with Python,Steven Bird, Ewan Klein 和Edward Loper,Copyright © 2014 作者所有。本章依据Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License [http://creativecommons.org/licenses/by-nc-nd/3.0/us/] 条款,与自然语言工具包 [http://nltk.org/] 3.0 版一起发行。
本文档构建于星期三 2015 年 7 月 1 日 12:30:05 AEST