我曾尝试在nltk中使用语音(或POS)标记器,但使用退避功能却无法使它同时使用多个ngram标记器。我读到您使用更多的标记器来获得更高的分数,但对我来说不起作用。我希望它首先使用更多的单词,然后少使用一个单词。我这样尝试过
import nltk
from nltk.corpus import brown
#sentence = brown.sents(categories = "news")
trains = brown.tagged_sents(categories = "news")
from nltk import NgramTagger
fortest = ["hi", "how","are", "you"]
tagger = (nltk.NgramTagger (n, trains, backoff=n-1) for n in range (3))
print tagger.tag(fortest)
但这给了我错误AttributeError:'generator'对象没有属性'tag'
所以我没有列表:
for n in range(3):
tagger = nltk.NgramTagger(n, trains, backoff=n-1)
但是然后我得到:
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nltk/tag/sequential.py", line 271, in __init__
ContextTagger.__init__(self, model, backoff)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nltk/tag/sequential.py", line 121, in __init__
SequentialBackoffTagger.__init__(self, backoff)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nltk/tag/sequential.py", line 46, in __init__
self._taggers = [self] + backoff._taggers AttributeError: 'int' object has no attribute '_taggers'
请帮忙,因为我是python新手。
最佳答案
Spaceghost是正确的,您需要提供对实际NgramTagger
对象的引用作为backoff
参数,而不仅仅是int
。仅将数字用作退避是没有意义的-创建新的标记器时,它不知道在哪里寻找具有较小相对上下文的先前创建的标记器。
这就是为什么您得到AttributeError: 'int' object has no attribute '_taggers'
的原因。 NLTK正在寻找从SequentialBackoffTagger
继承的类的对象。
根据您的range(3)
,我猜您实际上是想要一个三字母组标记器,其后退到bigram标记,而后退到unigram标记。
您可以尝试类似的方法,
from nltk.corpus import brown
from nltk import NgramTagger
trains = brown.tagged_sents(categories="news")
tagger = None # None here is okay since it's the default argument anyway
for n in range(1,4): # start at unigrams (1) up to and including trigrams (3)
tagger = NgramTagger(n, trains, backoff=tagger)
注意:无需多次导入nltk。
>>> tagger.tag('hi how are you'.split())
[('hi', None), ('how', 'WRB'), ('are', 'BER'), ('you', 'PPSS')]
请注意,我们为诸如“ hi”之类的单词的POS获得
None
,因为它不在给定语料库中出现(布朗的新闻类别)。如果需要的话,您可以通过以下方式设置默认标记器:初始设置tagger
(在for循环之前),例如,from nltk import DefaultTagger
tagger = DefaultTagger('NN')