【语言处理与Python】7.5命名实体识别/7.6关系抽取
7.5命名实体识别(NER)
目标是识别所有文字提及的命名实体。
可以分成两个子任务:确定NE的边界和确定其类型。
NLTK提供了一个已经训练好的可以识别命名实体的分类器,如果我们设置参数binary=True,那么命名实体只被标注为NE,没有类型标签。可以通过代码来看:
>>>sent = nltk.corpus.treebank.tagged_sents()[22] >>>print nltk.ne_chunk(sent, binary=True) (S The/DT (NE U.S./NNP) is/VBZ one/CD ... according/VBG to/TO (NE Brooke/NNPT./NNPMossman/NNP) ...) >>>print nltk.ne_chunk(sent) (S The/DT (GPE U.S./NNP) is/VBZ one/CD ... according/VBG to/TO (PERSON Brooke/NNPT./NNPMossman/NNP) ...)
7.6关系抽取
一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。
进行这一任务的方法之一,就是寻找所有的(X,α, Y)形式的三元组,我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词in的字符串。
特殊的正则表达式(?!\b.+ing\b)是一个否定预测先行断言,允许我们忽略如success in supervising the transition of中的字符串,其中in 后面跟一个动名词。
>>>IN = re.compile(r'.*\bin\b(?!\b.+ing)') >>>for docin nltk.corpus.ieer.parsed_docs('NYT_19980315'): ... for rel in nltk.sem.extract_rels('ORG', 'LOC', doc, ... corpus='ieer',pattern = IN): ... print nltk.sem.show_raw_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 businessincubator basedin' [LOC: 'Los Angeles'] [ORG: 'Open Text']', basedin' [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 ThalerGroup']'in' [LOC: 'New York'] [ORG: 'BBDO South']'in' [LOC: 'Atlanta'] [ORG: 'Georgia-Pacific'] 'in' [LOC: 'Atlanta']
如前文所示,CoNLL2002命名实体语料库的荷兰语部分不只包含命名实体标注,也包含词性标注。这允许我们设计对这些标记敏感的模式,如下面的例子所示。show_clause()方法以分条形式输出关系,其中二元关系符号作为参数relsym的值被指定。
>>>from nltk.corpusimport conll2002 >>>vnv= """ ... ( ... is/V| #3rdsing present and ... was/V| #past forms of the verb zijn ('be') ... werd/V| #and also present ... wordt/V #pastof worden('become') ... ) ... .* #followed byanything ... van/Prep #followed byvan('of') ... """ >>>VAN= re.compile(vnv, re.VERBOSE) >>>for docin conll2002.chunked_sents('ned.train'): ... for r in nltk.sem.extract_rels('PER', 'ORG', doc, ... corpus='conll2002', pattern=VAN): ... print nltk.sem.show_clause(r,relsym="VAN") VAN("cornet_d'elzius",'buitenlandse_handel') VAN('johan_rottiers','kardinaal_van_roey_instituut') VAN('annie_lennox','eurythmics')