我使用python和java来运行斯坦福NER标记器,但我看到结果的差异.
例如,当我输入句子"参与使用ERwin作为主要软件的数据建模的所有方面.",
JAVA结果:
"ERwin": "PERSON"
Python结果:
In [6]: NERTagger.tag("Involved in all aspects of data modeling using ERwin as the primary software for this.".split()) Out [6]:[(u'Involved', u'O'), (u'in', u'O'), (u'all', u'O'), (u'aspects', u'O'), (u'of', u'O'), (u'data', u'O'), (u'modeling', u'O'), (u'using', u'O'), (u'ERwin', u'O'), (u'as', u'O'), (u'the', u'O'), (u'primary', u'O'), (u'software', u'O'), (u'for', u'O'), (u'this.', u'O')]
Python nltk包装器无法将"ERwin"作为PERSON捕获.
这里有趣的是Python和Java使用2015-04-20发布的相同训练数据(english.all.3class.caseless.distsim.crf.ser.gz).
我的最终目标是让python以与Java相同的方式工作.
我在nltk.tag中查看StanfordNERTagger,看看有什么我可以修改的.下面是包装代码:
class StanfordNERTagger(StanfordTagger): """ A class for Named-Entity Tagging with Stanford Tagger. The input is the paths to: - a model trained on training data - (optionally) the path to the stanford tagger jar file. If not specified here, then this jar file must be specified in the CLASSPATH envinroment variable. - (optionally) the encoding of the training data (default: UTF-8) Example: >>> from nltk.tag import StanfordNERTagger >>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz') # doctest: +SKIP >>> st.tag('Rami Eid is studying at Stony Brook University in NY'.split()) # doctest: +SKIP [('Rami', 'PERSON'), ('Eid', 'PERSON'), ('is', 'O'), ('studying', 'O'), ('at', 'O'), ('Stony', 'ORGANIZATION'), ('Brook', 'ORGANIZATION'), ('University', 'ORGANIZATION'), ('in', 'O'), ('NY', 'LOCATION')] """ _SEPARATOR = '/' _JAR = 'stanford-ner.jar' _FORMAT = 'slashTags' def __init__(self, *args, **kwargs): super(StanfordNERTagger, self).__init__(*args, **kwargs) @property def _cmd(self): # Adding -tokenizerFactory edu.stanford.nlp.process.WhitespaceTokenizer -tokenizerOptions tokenizeNLs=false for not using stanford Tokenizer return ['edu.stanford.nlp.ie.crf.CRFClassifier', '-loadClassifier', self._stanford_model, '-textFile', self._input_file_path, '-outputFormat', self._FORMAT, '-tokenizerFactory', 'edu.stanford.nlp.process.WhitespaceTokenizer', '-tokenizerOptions','\"tokenizeNLs=false\"'] def parse_output(self, text, sentences): if self._FORMAT == 'slashTags': # Joint together to a big list tagged_sentences = [] for tagged_sentence in text.strip().split("\n"): for tagged_word in tagged_sentence.strip().split(): word_tags = tagged_word.strip().split(self._SEPARATOR) tagged_sentences.append((''.join(word_tags[:-1]), word_tags[-1])) # Separate it according to the input result = [] start = 0 for sent in sentences: result.append(tagged_sentences[start:start + len(sent)]) start += len(sent); return result raise NotImplementedError
或者,如果是因为使用了不同的分类器(在java代码中,它似乎使用AbstractSequenceClassifier,另一方面,python nltk包装器使用CRFClassifier.)有没有一种方法可以在python包装器中使用AbstractSequenceClassifier?
尝试maxAdditionalKnownLCWords
在CoreNLP的属性文件(或命令行)中设置为0,如果可能,也尝试为NLTK 设置为0.这会禁用一个选项,允许NER系统稍微从测试时间数据中学习,这可能会导致偶尔出现略微不同的结果.