пометка pos в nltk с помощью отложенных ngrams

Я попытался сделать тег части речи (или POS) в nltk, но я не могу заставить его работать более чем для одного тега 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: объект «генератор» не имеет атрибута «тег»

поэтому я делаю это без списка:

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.


person user2492738    schedule 23.06.2013    source источник


Ответы (2)


Spaceghost прав, вам нужно предоставить ссылку на фактический объект NgramTagger в качестве аргумента backoff, а не только int. Просто использовать число в качестве отсрочки бессмысленно — при создании нового тегера он понятия не имеет, где искать ранее созданный тегер с меньшим относительным контекстом.

Вот почему вы получаете AttributeError: 'int' object has no attribute '_taggers'. NLTK ищет объект класса, наследуемого от SequentialBackoffTagger.

Основываясь на вашем range(3), я предполагаю, что вы на самом деле хотели использовать теггер триграмм с откатом к теггеру биграмм, с откатом к теггеру юниграмм >.

Вы можете попробовать что-то вроде,

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')]

Обратите внимание, мы получаем None для POS таких слов, как «привет», поскольку оно не встречается в данном корпусе (категория новостей Брауна). Вы можете установить тег по умолчанию, если хотите, изначально установив tagger (перед циклом for), например,

from nltk import DefaultTagger
tagger = DefaultTagger('NN')
person Jared    schedule 24.06.2013

Параметр отсрочки должен указывать на другой тегировщик, который следует использовать, когда текущий показал себя лучше всего. Вам нужно определить второй тегировщик или использовать значение по умолчанию, а затем изменить свой код, чтобы использовать его. Что-то вроде этого:

default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)
tagger = nltk.NgramTagger(n, trains, backoff=default_tagger)
person Spaceghost    schedule 23.06.2013