python - 斯坦福 NER 标注器 NLTK(python)与 JAVA 的结果差异

标签 python nlp nltk stanford-nlp named-entity-recognition

我同时使用 python 和 java 来运行 Stanford NER 标记器,但我看到了结果的差异。

例如,当我输入“Involved in all aspects of data modeling using ERwin as the primary software for this.”这句话时,

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?

最佳答案

尝试在 CoreNLP 的属性文件(或命令行)中将 maxAdditionalKnownLCWords 设置为 0,如果可能,也将 NLTK 设置为 0。这会禁用允许 NER 系统从测试时间数据中学习一点点的选项,这可能会导致偶尔出现轻微不同的结果。

关于python - 斯坦福 NER 标注器 NLTK(python)与 JAVA 的结果差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34626555/

相关文章:

python - 如何在不使用 "for"循环的情况下遍历 Python 中的列表?

python - 找不到满足 ruamel 要求的版本(来自版本 : ) No matching distribution found for ruamel

nlp - Google Colab 上传词嵌入

python - Nltk和Python,绘制ROC曲线

python - 如何导入文本文件以适合此聚类算法?

python - 在 MacOS Sierra 上安装 Pillow

python - 为什么变量名两边带括号的 del(x) 有效?

nlp - 如何自定义 spaCy 的分词器以排除正则表达式描述的拆分短语

parsing - 在哪里可以找到有关 Berkeley Parser 的文档?

python - nltk - gzip 文件语料库