我一直在使用Java和Python中的斯坦福大学的命名实体识别(NER)标记器(http://nlp.stanford.edu/software/CRF-NER.shtml),并且我偶然发现了一个我无法解决的不一致问题。
这是我用的句子作为例子:
"I said hello to Mr. Jones, and then I went on my way."
在NER标记器的在线演示(http://nlp.stanford.edu:8080/ner/process)中,这将返回"Jones"
作为3级模型的命名实体,并将"Mr. Jones"
作为4级和7-班级模特。我希望它返回"Mr. Jones"
,这是Python的NLTK中的NE_chunker没有问题。
但是,当我在我的机器上尝试这个(使用Java GUI或通过Python)时,我只得到"Jones"
,而没有"Mr."
。有趣的是,如果我删除" Mr"在这句话中:
"I said hello to Mr Jones, and then I went on my way."
然后我得到"Mr Jones"
作为我的命名实体。更奇怪的是,如果我删除所有标点符号:
"I said hello to Mr Jones and then I went on my way"
我再次只获得"Jones"
。我不知道为什么会出现这种不一致。特别是因为在线演示版本正确地返回了所有三种句子中所有形式的"Mr Jones"
7类模型(我更喜欢用于我的项目)。
为什么会发生这种情况?
工具/版本:Windows 7; Java JDK 1.8.0_121; Stanford CoreNLP 3.7.0(2016-10-31);斯坦福大学NER 3.7.0(2016-10-31); Python 3.5; NLTK 3.2.1
重现结果的Python代码:
import nltk
import os
stanford_dir = '/my_path_to/stanford_files/'
jarfile = stanford_dir + 'stanford_ner.jar'
model_7class = stanford_dir + 'classifiers/English.muc.7class.distsim.crf.ser.gz'
postagger_jar = stanford_dir + 'stanford_postagger.jar'
java_path = '/my_path_to/Java/jdk1.8.0_121/bin/java.exe'
os.environ['JAVAHOME'] = java_path
st = nltk.tag.StanfordNERTagger(model_filename=model_7class,path_to_jar=jarfile, encoding='utf-8')
st_tokenize = nltk.tokenize.StanfordTokenizer(path_to_jar=postagger_jar).tokenize
my_sent = 'I said hello to Mr. Jones, and then I went on my way.'
tokens = st_tokenize(my_sent)
tags = st.tag(tokens)
named_entities = [word for word,tag in tags if tag != 'O']
print(named_entities)