6 关系抽取
一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。如前所述,我们通常会寻找指定类型的命名实体之间的关系。进行这一任务的方法之一是首先寻找所有 X, α, Y)形式的三元组,其中 X 和 Y 是指定类型的命名实体,α表示 X 和 Y 之间关系的字符串。然后我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词 in 的字符串。特殊的正则表达式(?!\b.+ing\b)
是一个否定预测先行断言,允许我们忽略如 success in supervising the transition of 中的字符串,其中 in 后面跟一个动名词。
>>> IN = re.compile(r'.*\bin\b(?!\b.+ing)')
>>> for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
... for rel in nltk.sem.extract_rels('ORG', 'LOC', doc,
... corpus='ieer', pattern = IN):
... print(nltk.sem.rtuple(rel))
[ORG: 'WHYY'] 'in' [LOC: 'Philadelphia']
[ORG: 'McGlashan & Sarrail'] 'firm in' [LOC: 'San Mateo']
[ORG: 'Freedom Forum'] 'in' [LOC: 'Arlington']
[ORG: 'Brookings Institution'] ', the research group in' [LOC: 'Washington']
[ORG: 'Idealab'] ', a self-described business incubator based in' [LOC: 'Los Angeles']
[ORG: 'Open Text'] ', based in' [LOC: 'Waterloo']
[ORG: 'WGBH'] 'in' [LOC: 'Boston']
[ORG: 'Bastille Opera'] 'in' [LOC: 'Paris']
[ORG: 'Omnicom'] 'in' [LOC: 'New York']
[ORG: 'DDB Needham'] 'in' [LOC: 'New York']
[ORG: 'Kaplan Thaler Group'] 'in' [LOC: 'New York']
[ORG: 'BBDO South'] 'in' [LOC: 'Atlanta']
[ORG: 'Georgia-Pacific'] 'in' [LOC: 'Atlanta']
搜索关键字 in 执行的相当不错,虽然它的检索结果也会误报,例如[ORG: House Transportation Committee] , secured the most money in the [LOC: New York]
;一种简单的基于字符串的方法排除这样的填充字符串似乎不太可能。
如前文所示,conll2002
命名实体语料库的荷兰语部分不只包含命名实体标注,也包含词性标注。这允许我们设计对这些标记敏感的模式,如下面的例子所示。clause()
方法以分条形式输出关系,其中二元关系符号作为参数relsym
的值被指定。
>>> from nltk.corpus import conll2002
>>> vnv = """
... (
... is/V| # 3rd sing present and
... was/V| # past forms of the verb zijn ('be')
... werd/V| # and also present
... wordt/V # past of worden ('become)
... )
... .* # followed by anything
... van/Prep # followed by van ('of')
... """
>>> VAN = re.compile(vnv, re.VERBOSE)
>>> for doc in conll2002.chunked_sents('ned.train'):
... for r in nltk.sem.extract_rels('PER', 'ORG', doc,
... corpus='conll2002', pattern=VAN):
... print(nltk.sem.clause(r, relsym="VAN")) ![[1]](/projects/nlp-py-2e-zh/Images/f4891d12ae20c39b685951ad3cddf1aa.jpg)
VAN("cornet_d'elzius", 'buitenlandse_handel')
VAN('johan_rottiers', 'kardinaal_van_roey_instituut')
VAN('annie_lennox', 'eurythmics')
注意
轮到你来:替换最后一行为print(rtuple(rel, lcon=True, rcon=True))
。这将显示实际的词表示两个 NE 之间关系以及它们左右的默认 10 个词的窗口的上下文。在一本荷兰语词典的帮助下,你也许能够找出为什么结果VAN('annie_lennox', 'eurythmics')
是个误报。