【问题标题】:NLTK : combining stanford tagger and personal taggerNLTK:结合斯坦福标注器和个人标注器
【发布时间】:2015-05-11 08:24:46
【问题描述】:

我的项目的目标是回答查询,例如: “我正在寻找在 Google 工作的 20 至 30 岁的美国女性” 然后我必须处理查询并查看数据库以找到答案。

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

现在,我有这样的代码:

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

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

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

谢谢!

【问题讨论】:

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


    【解决方案1】:

    带有 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 模型是使用斯坦福 CoreNLP 或斯坦福 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')]
    

    这是斯坦福 NER 页面的链接:

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

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

    【讨论】:

    • 非常感谢!这正是我所需要的。我认为如果它在 NLTK 中默认存在那将是一件好事,但这只是我的意见!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    相关资源
    最近更新 更多