• 6 关系抽取

    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')是个误报。