信息提取系统的流程。
这个流程图中的左边部分其实就是前面几节提到的内容,当我们拿到一个字符串文本,要先对数据进行预处理,即先对句子进行分割,然后再对句子进行分词,接着给分词进行词性标注,再接着就是这节内容提到的实体识别,实体识别其实就是对已标注的词汇进行分块,分块后就可以提取关系了,确定临近实体之间是否有某种指定的关系。
1. 具体分块是怎么实现的呢?
分块可以即根据每个词的词性标注,确定块标记
class UnigramChunker(nltk.ChunkParserI):
def __init__(self,train_sents):
train_data=[[(t,c) for w,t,c in nltk.chunk.tree2conlltags(sent)]
for sent in train_sents]
self.tagger=nltk.UnigramTagger(train_data)
def parse(self,sentence):
pos_tags=[pos for (word,pos) in sentence]
tagged_pos_tags=self.tagger.tag(pos_tags)
chunktags=[chunktag for (pos,chunktag) in tagged_pos_tags]
conlltags=[(word,pos,chunktag) for ((word,pos),chunktag)
in zip(sentence,chunktags)]
return nltk.chunk.conlltags2tree(conlltags)
基于分类器的分块器,除了使用词的词性外,还使用了词的信息内容,主要可以提取多个特征,训练分类器
此外,分块中语言模式的定义,其中每个标识符后必须分行
A grammar contains one or more clauses in the following form::
|
| NP:
| {<DT|JJ>} # chunk determiners and adjectives
| }<[\.VI].*>+{ # chink any tag beginning with V, I, or .
| <.*>}{<DT> # split a chunk at a determiner
| <DT|JJ>{}<NN.*> # merge chunk ending with det/adj
| # with one starting with a noun
"""
grammer=r"""
NP:{<DT||JJ|NN.*>+}
PP:{<IN><NP>}
VP:{<VB.*><NP|PP|CLAUSE>+$}
CLAUSE:{<NP><VP>}
"""
cp=nltk.RegexpParser(grammer)
cp=nltk.RegexpParser(grammer,loop=2) #让分块器在循环模式中循环,循环的次数为2
2. 命名实体识别
命名实体识别,可以分为两个子任务:确定NE的边界和类型
命名实体的困难,首先在于字典覆盖不全,其次是命名实体具有二义性,以及多词名称
适合用基于分类器类型的方法来处理
IN=re.compile(r'.*\bin\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.show_raw_rtuple(rel)
信息提取系统着眼于文本中提到的相互临近的实体,并试图确定这些实体之间是否有指定的关系