6 关系抽取

一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。如前所述,我们通常会寻找指定类型的命名实体之间的关系。进行这一任务的方法之一是首先寻找所有 X, α, Y)形式的三元组,其中 XY 是指定类型的命名实体,α表示 XY 之间关系的字符串。然后我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词 in 的字符串。特殊的正则表达式(?!\b.+ing\b)是一个否定预测先行断言,允许我们忽略如 success in supervising the transition of 中的字符串,其中 in 后面跟一个动名词。

  1. >>> IN = re.compile(r'.*\bin\b(?!\b.+ing)')
  2. >>> for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
  3. ... for rel in nltk.sem.extract_rels('ORG', 'LOC', doc,
  4. ... corpus='ieer', pattern = IN):
  5. ... print(nltk.sem.rtuple(rel))
  6. [ORG: 'WHYY'] 'in' [LOC: 'Philadelphia']
  7. [ORG: 'McGlashan & Sarrail'] 'firm in' [LOC: 'San Mateo']
  8. [ORG: 'Freedom Forum'] 'in' [LOC: 'Arlington']
  9. [ORG: 'Brookings Institution'] ', the research group in' [LOC: 'Washington']
  10. [ORG: 'Idealab'] ', a self-described business incubator based in' [LOC: 'Los Angeles']
  11. [ORG: 'Open Text'] ', based in' [LOC: 'Waterloo']
  12. [ORG: 'WGBH'] 'in' [LOC: 'Boston']
  13. [ORG: 'Bastille Opera'] 'in' [LOC: 'Paris']
  14. [ORG: 'Omnicom'] 'in' [LOC: 'New York']
  15. [ORG: 'DDB Needham'] 'in' [LOC: 'New York']
  16. [ORG: 'Kaplan Thaler Group'] 'in' [LOC: 'New York']
  17. [ORG: 'BBDO South'] 'in' [LOC: 'Atlanta']
  18. [ORG: 'Georgia-Pacific'] 'in' [LOC: 'Atlanta']

搜索关键字 in 执行的相当不错,虽然它的检索结果也会误报,例如[ORG: House Transportation Committee] , secured the most money in the [LOC: New York];一种简单的基于字符串的方法排除这样的填充字符串似乎不太可能。

如前文所示,conll2002命名实体语料库的荷兰语部分不只包含命名实体标注,也包含词性标注。这允许我们设计对这些标记敏感的模式,如下面的例子所示。clause()方法以分条形式输出关系,其中二元关系符号作为参数relsym的值被指定[1]

  1. >>> from nltk.corpus import conll2002
  2. >>> vnv = """
  3. ... (
  4. ... is/V| # 3rd sing present and
  5. ... was/V| # past forms of the verb zijn ('be')
  6. ... werd/V| # and also present
  7. ... wordt/V # past of worden ('become)
  8. ... )
  9. ... .* # followed by anything
  10. ... van/Prep # followed by van ('of')
  11. ... """
  12. >>> VAN = re.compile(vnv, re.VERBOSE)
  13. >>> for doc in conll2002.chunked_sents('ned.train'):
  14. ... for r in nltk.sem.extract_rels('PER', 'ORG', doc,
  15. ... corpus='conll2002', pattern=VAN):
  16. ... print(nltk.sem.clause(r, relsym="VAN")) ![[1]](/projects/nlp-py-2e-zh/Images/f4891d12ae20c39b685951ad3cddf1aa.jpg)
  17. VAN("cornet_d'elzius", 'buitenlandse_handel')
  18. VAN('johan_rottiers', 'kardinaal_van_roey_instituut')
  19. VAN('annie_lennox', 'eurythmics')

注意

轮到你来:替换最后一行[1]print(rtuple(rel, lcon=True, rcon=True))。这将显示实际的词表示两个 NE 之间关系以及它们左右的默认 10 个词的窗口的上下文。在一本荷兰语词典的帮助下,你也许能够找出为什么结果VAN('annie_lennox', 'eurythmics')是个误报。