我想从utf-8文本中提取实体,但似乎无法使nltk.stanford.NERTagger返回长于1的ngrams。
任何人都知道如何做到这一点?
import nltk
NER = nltk.stanford.NERTagger("/Library/Java/Extensions/NER/classifiers/english.all.3class.distsim.crf.ser.gz",
"/Library/Java/Extensions/NER/stanford-ner.jar")
NER.tag('Game of Thrones by George R. R. Martin'.split())
输出是这样的:
[[(u'Game', u'O'),
(u'of', u'O'),
(u'Thrones', u'O'),
(u'by', u'O'),
(u'George', u'PERSON'),
(u'R.', u'PERSON'),
(u'R.', u'PERSON'),
(u'Martin', u'PERSON')]]
我需要这样的东西:
[[(u'Game', u'O'),
(u'of', u'O'),
(u'Thrones', u'O'),
(u'by', u'O'),
(u'George R. R. Martin', u'PERSON')]]
我的一位同事用Java调用相同的stanford NLP算法,并且这些实体不会被分解。
谢谢!
===== LIKELY DUPLICATE =====
Chunking Stanford Named Entity Recognizer (NER) outputs from NLTK format
答案 0 :(得分:4)
根据亚历克西斯在http://sense.qbox.io/gist/6258f8c9ee64878a1835b3e9ea2b54e5cf6b1d9e中的回答,斯坦福大学的标记器没有公开区分两个相邻命名实体和一个占用多个标记的命名实体的方法。
话虽这么说,那里提到的解决方案只是将相同标记的相邻标记组合在一起,这通常是一种有效的启发式方法(尽管绝对不是万无一失):
from itertools import groupby
from pprint import pprint
result = NER.tag('Game of Thrones by George R. R. Martin'.split())
chunked = []
for tag, chunk in groupby(result, lambda x:x[1]):
if tag == "O":
chunked.extend((w,t) for (w,t) in chunk)
else:
chunked.append((" ".join(w for (w,t) in chunk), tag))
pprint(chunked)
提供输出:
[(u'Game', u'O'),
(u'of', u'O'),
(u'Thrones', u'O'),
(u'by', u'O'),
(u'George R. R. Martin', u'PERSON')]