NLTK:结合斯坦福标注器和个人标注器

NLTK : combining stanford tagger and personal tagger

我的项目的目标是回答查询,例如: "I am looking for American women between 20 and 30 years old who work in Google" 然后我必须处理查询并查看数据库以找到答案。

为此,我需要结合 Stanford 3-class NERTagger 和我自己的标注器。事实上,我的 NER 标注器可以标注年龄、国籍和性别。但是我需要 Stanford 标记器来标记组织,因为我没有任何培训文件。

现在,我有这样的代码:

def __init__(self, q):
    self.userQuery = q
def get_tagged_tokens(self):
    st = NERTagger('C:\stanford-ner-2015-01-30\my-ner-model.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar')
    result = st.tag(self.userQuery.split())[0]
    return result

我想要这样的东西:

def get_tagged_tokens(self):
    st = NERTagger('C:\stanford-ner-2015-01-30\my-ner-model.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar')
    st_def = NERTagger('C:\stanford-ner-2015-01-30\classifiers\english.all.3class.distsim.crf.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar')
    tagger = BackoffTagger([st, st_def])
    result = st.tag(self.userQuery.split())[0]
    return result

这意味着标注器首先使用我的标注器,然后使用斯坦福标注器来标注未标注的词。

是否可以将我的模型与斯坦福模型结合起来只是为了标记组织?如果是,执行此操作的最佳方法是什么?

谢谢!

带有 Stanford CoreNLP 3.5.2 的新 NERClassifierCombiner 或新 Stanford NER 3.5.2 添加了命令行功能,可以使用 NLTK 轻松获得此效果。

当您提供序列化分类器列表时,NERClassifierCombiner 将按顺序 运行 它们。在一个标记器标记句子后,没有其他标记器将标记已经标记的标记。所以请注意,在我的演示代码中,我提供了 2 个分类器作为示例。它们按您放置的顺序 运行。如果我没记错的话,我相信你最多可以放10个!

首先,确保您拥有 Stanford CoreNLP 3.5.2 或 Stanford NER 3.5.2 的最新副本,以便您拥有具有此新功能的正确 .jar 文件。

其次,确保您的自定义 NER 模型是使用 Stanford CoreNLP 或 Stanford NER 构建的,否则将无法正常工作!如果您使用旧版本应该没问题。

第三,我提供了一些应该可以工作的示例代码,主要目的是继承 NERTagger:

如果人们愿意,我可以考虑将它推送到 NLTK,所以默认情况下它就在那里!

这是一些示例代码(它有点老套,因为我只是匆匆忙忙把它赶出去,例如在 NERComboTagger 的构造函数中,第一个参数是 classifier_path1 是没有意义的,但代码会如果我没有在那里放一个有效的文件就会崩溃):

#!/usr/bin/python

from nltk.tag.stanford import NERTagger

class NERComboTagger(NERTagger):

  def __init__(self, *args, **kwargs):
    self.stanford_ner_models = kwargs['stanford_ner_models']
    kwargs.pop("stanford_ner_models")
    super(NERComboTagger,self).__init__(*args, **kwargs)

  @property
  def _cmd(self):
    return ['edu.stanford.nlp.ie.NERClassifierCombiner',
            '-ner.model',
            self.stanford_ner_models,
            '-textFile',
            self._input_file_path,
            '-outputFormat',
            self._FORMAT,
            '-tokenizerFactory',
            'edu.stanford.nlp.process.WhitespaceTokenizer',
            '-tokenizerOptions',
            '\"tokenizeNLs=false\"']

classifier_path1 = "classifiers/english.conll.4class.distsim.crf.ser.gz"
classifier_path2 = "classifiers/english.muc.7class.distsim.crf.ser.gz"

ner_jar_path = "stanford-ner.jar"

st = NERComboTagger(classifier_path1,ner_jar_path,stanford_ner_models=classifier_path1+","+classifier_path2)

print st.tag("Barack Obama is from Hawaii .".split(" "))  

注意子类中的主要变化是 _cmd 返回的内容。

另请注意,我 运行 在解压缩的文件夹 stanford-ner-2015-04-20 中,因此路径是相对于它的。

我得到这个输出:

[('Barack','PERSON'), ('Obama', 'PERSON'), ('is','O'), ('from', 'O'), ('Hawaii', 'LOCATION'), ('.', 'O')]

这是 Stanford NER 页面的 link:

http://nlp.stanford.edu/software/CRF-NER.shtml

如果您需要更多帮助或我的代码中有任何错误,请告诉我,我可能在 t运行 抄写时犯了错误,但它在我的笔记本电脑上有效!