【问题标题】:custom tagging with nltk使用 nltk 进行自定义标记
【发布时间】:2011-08-20 15:11:58
【问题描述】:

我正在尝试创建一种类似英语的小型语言来指定任务。基本思想是将语句拆分为动词和名词短语,这些动词应适用。我正在使用 nltk,但没有得到我希望的结果,例如:

>>> nltk.pos_tag(nltk.word_tokenize("select the files and copy to harddrive'"))
[('select', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('and', 'CC'), ('copy', 'VB'), ('to', 'TO'), ("harddrive'", 'NNP')]
>>> nltk.pos_tag(nltk.word_tokenize("move the files to harddrive'"))
[('move', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('to', 'TO'), ("harddrive'", 'NNP')]
>>> nltk.pos_tag(nltk.word_tokenize("copy the files to harddrive'"))
[('copy', 'NN'), ('the', 'DT'), ('files', 'NNS'), ('to', 'TO'), ("harddrive'", 'NNP')]

在每种情况下,它都没有意识到第一个词(选择、移动和复制)是动词。我知道我可以创建自定义标记器和语法来解决这个问题,但与此同时,当很多这些东西超出我的范围时,我会犹豫是否要重新发明轮子。我特别希望有一个也可以处理非英语语言的解决方案。

所以无论如何,我的问题之一是: 这种语法有更好的标注器吗? 有没有办法让现有的标注器更频繁地使用动词形式而不是名词形式? 有没有办法训练标注者? 有没有更好的方法?

【问题讨论】:

    标签: python nltk


    【解决方案1】:

    一种解决方案是创建一个手动UnigramTagger,它会退回到 NLTK 标记器。像这样的:

    >>> import nltk.tag, nltk.data
    >>> default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)
    >>> model = {'select': 'VB'}
    >>> tagger = nltk.tag.UnigramTagger(model=model, backoff=default_tagger)
    

    然后你得到

    >>> tagger.tag(['select', 'the', 'files'])
    [('select', 'VB'), ('the', 'DT'), ('files', 'NNS')]
    

    只要您有适当的默认标记器,同样的方法也适用于非英语语言。您可以使用来自nltk-trainertrain_tagger.py 和适当的语料库来训练自己的标注器。

    【讨论】:

      【解决方案2】:

      Jacob 的回答很到位。但是,要扩展它,您可能会发现您需要的不仅仅是一元组。

      例如,考虑这三个句子:

      select the files
      use the select function on the sockets
      the select was good
      

      这里,“选择”一词分别用作动词、形容词和名词。一元标记器将无法对此进行建模。即使是二元标记器也无法处理它,因为其中两个案例共享相同的前面单词(即“the”)。您需要一个三元组标记器才能正确处理这种情况。

      import nltk.tag, nltk.data
      from nltk import word_tokenize
      default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)
      
      def evaluate(tagger, sentences):
          good,total = 0,0.
          for sentence,func in sentences:
              tags = tagger.tag(nltk.word_tokenize(sentence))
              print tags
              good += func(tags)
              total += 1
          print 'Accuracy:',good/total
      
      sentences = [
          ('select the files', lambda tags: ('select', 'VB') in tags),
          ('use the select function on the sockets', lambda tags: ('select', 'JJ') in tags and ('use', 'VB') in tags),
          ('the select was good', lambda tags: ('select', 'NN') in tags),
      ]
      
      train_sents = [
          [('select', 'VB'), ('the', 'DT'), ('files', 'NNS')],
          [('use', 'VB'), ('the', 'DT'), ('select', 'JJ'), ('function', 'NN'), ('on', 'IN'), ('the', 'DT'), ('sockets', 'NNS')],
          [('the', 'DT'), ('select', 'NN'), ('files', 'NNS')],
      ]
      
      tagger = nltk.TrigramTagger(train_sents, backoff=default_tagger)
      evaluate(tagger, sentences)
      #model = tagger._context_to_tag
      

      请注意,您可以使用 NLTK 的 NgramTagger 使用任意数量的 n-gram 来训练标注器,但通常在使用 trigram 之后您不会获得太多性能提升。

      【讨论】:

      • 是否可以使用模型(如 Jacobs 答案)和训练句子(如此答案)?
      【解决方案3】:

      见雅各布的回答。

      在以后的版本中(至少 nltk 3.2)nltk.tag._POS_TAGGER 不存在。默认标注器通常下载到 nltk_data/taggers/ 目录,例如:

      >>> import nltk
      >>> nltk.download('maxent_treebank_pos_tagger') 
      

      用法如下。

      >>> import nltk.tag, nltk.data
      >>> tagger_path = '/path/to/nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle'
      >>> default_tagger = nltk.data.load(tagger_path)
      >>> model = {'select': 'VB'}
      >>> tagger = nltk.tag.UnigramTagger(model=model, backoff=default_tagger)
      

      另请参阅:How to do POS tagging using the NLTK POS tagger in Python

      【讨论】:

        【解决方案4】:

        巴德的回答是正确的。另外,根据this link

        如果您的 nltk_data 包已正确安装,则 NLTK 知道它们在您的系统上的位置,您无需传递绝对路径。

        意思是,你可以说

        tagger_path = '/path/to/nltk_data/taggers/maxent_treebank_pos_tagger/english.pickle'
        default_tagger = nltk.data.load(tagger_path)
        

        【讨论】:

        • 一般情况下会是 'taggers/maxent_treebank_pos_tagger/english.pickle'
        猜你喜欢
        • 1970-01-01
        • 2014-07-07
        • 2016-11-18
        • 2011-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多