我正在尝试使用Python NLTK中的斯坦福命名实体识别器(NER)提取人员和组织的列表。 当我跑步时:
from nltk.tag.stanford import NERTagger
st = NERTagger('/usr/share/stanford-ner/classifiers/all.3class.distsim.crf.ser.gz',
'/usr/share/stanford-ner/stanford-ner.jar')
r=st.tag('Rami Eid is studying at Stony Brook University in NY'.split())
print(r)
输出为:
[('Rami', 'PERSON'), ('Eid', 'PERSON'), ('is', 'O'), ('studying', 'O'),
('at', 'O'), ('Stony', 'ORGANIZATION'), ('Brook', 'ORGANIZATION'),
('University', 'ORGANIZATION'), ('in', 'O'), ('NY', 'LOCATION')]
我要的是从这个列表中提取以下形式的所有人员和组织:
Rami Eid
Sony Brook University
我试图遍历元组列表:
for x,y in i:
if y == 'ORGANIZATION':
print(x)
但这段代码每行只打印一个实体:
Sony
Brook
University
有了真实的数据,一句话就可以有多个组织、多个人,我如何才能在不同的实体之间设置界限呢?
由于@Vaulstein发现了link,很明显,经过训练的Stanford标记器(至少在2012年)是分布式的,不会将命名实体块化。来自the accepted answer:
您有以下选项:
收集同一个标记的单词;例如,标记
PERSON
的所有相邻单词应作为一个命名实体放在一起。这很简单,但它有时会合并不同的命名实体。(例如,New York, Boston [and] Baltimore
大约是三个城市,而不是一个。)编辑:这是Alvas的代码在接受的anwser中所做的。有关更简单的实现,请参见下文。使用
nltk.ne_recognize()
。它不使用斯坦福识别器,但它使用块实体。(它是一个名为entity tagger的IOB的包装器)。找出一种方法,在斯坦福tagger返回的结果基础上进行自己的分块。
为您感兴趣的域训练您自己的IOB命名实体chunker(使用斯坦福工具或NLTK的框架)。如果你有时间和资源去做正确的事情,它可能会给你最好的结果。
编辑:如果您只想拉出连续命名实体的运行(上面的选项1),您应该使用
itertools.groupby
:如果
netagged_words
是问题中的(word, type)
元组列表,则会生成:请再次注意,如果同一类型的两个命名实体相邻出现,则此方法将组合它们。E、 g.
New York, Boston [and] Baltimore
是关于三个城市,而不是一个。不完全按照主题作者的要求打印他想要的东西,也许这会有帮助
输出应该是这样的
I O B/B I O是指Inside,Outside,Begining(IOB),或有时又称aBegining,Inside,Outside(BIO)
Stanford NE tagger返回IOB/BIO风格的标签,例如
('Rami', 'PERSON'), ('Eid', 'PERSON')
被标记为PERSON,“Rami”是开始或NE块,“Eid”是内部。然后你就会看到任何非NE都会被标记为“O”。提取连续的NE chunk的想法与Named Entity Recognition with Regular Expression: NLTK非常相似,但是由于Stanford NE chunker API没有返回一个好的树来解析,因此必须执行以下操作:
[出局]:
但是请注意,如果两个ne是连续的,那么它可能是错误的,尽管如此,我仍然无法想到任何两个ne之间没有“O”的连续的例子。
正如@alexis所建议的,最好将stanford NE输出转换为NLTK树:
[出局]:
然后:
[出局]:
相关问题 更多 >
编程相关推荐