POS-Tagger невероятно медленный

Я использую nltk для создания n-грамм из предложений, сначала удаляя заданные стоп-слова. Однако nltk.pos_tag() работает очень медленно, на моем процессоре (Intel i7) занимает до 0,6 секунды.

Выход:

['The first time I went, and was completely taken by the live jazz band and atmosphere, I ordered the Lobster Cobb Salad.']
0.620481014252
["It's simply the best meal in NYC."]
0.640982151031
['You cannot go wrong at the Red Eye Grill.']
0.644664049149

Код:

for sentence in source:

    nltk_ngrams = None

    if stop_words is not None:   
        start = time.time()
        sentence_pos = nltk.pos_tag(word_tokenize(sentence))
        print time.time() - start

        filtered_words = [word for (word, pos) in sentence_pos if pos not in stop_words]
    else:
        filtered_words = ngrams(sentence.split(), n)

Это действительно так медленно или я что-то не так делаю?


person Stefan Falk    schedule 12.11.2015    source источник
comment
Можете ли вы опубликовать текст, который вы вводите? Какова спецификация вашей машины (скорость ЦП и ОЗУ)? Подключаетесь ли вы к облаку и как вы рассчитываете время функции? Также см. stackoverflow.com/questions/33558836/   -  person alvas    schedule 12.11.2015
comment
@alvas Это Intel i7 (указано в вопросе). 16 ГБ ОЗУ. Нет, это не в облаке, это локально. Вы можете увидеть в моем примере кода, как я это делаю.   -  person Stefan Falk    schedule 12.11.2015
comment
Вам необходимо распараллелить решение, если у вас огромный набор данных. В противном случае (если вы можете хранить помеченные предложения в оперативной памяти), просто соберите все помеченные предложения, а затем выполните фильтрацию.   -  person alvas    schedule 12.11.2015


Ответы (3)


Используйте pos_tag_sents для пометки нескольких предложений:

>>> import time
>>> from nltk.corpus import brown
>>> from nltk import pos_tag
>>> from nltk import pos_tag_sents
>>> sents = brown.sents()[:10]
>>> start = time.time(); pos_tag(sents[0]); print time.time() - start
0.934092998505
>>> start = time.time(); [pos_tag(s) for s in sents]; print time.time() - start
9.5061340332
>>> start = time.time(); pos_tag_sents(sents); print time.time() - start 
0.939551115036
person alvas    schedule 12.11.2015
comment
Очень хорошо! Использование pos_tag_sents() значительно повышает производительность. Странно, почему это так. Кажется, pos_tag() повторяет какую-то инициализацию или что-то в этом роде. - person Stefan Falk; 12.11.2015
comment
Это вопрос с довольно длинным ответом, но если вы зададите отдельный вопрос о том, как и почему это быстрее, кто-то может ответить. если никто не ответит, отвечу, когда освобожусь завтра вечером =) - person alvas; 12.11.2015
comment
Вот так ; ) - person Stefan Falk; 20.11.2015
comment
Вуаля, ответил кто-то другой =) - person alvas; 20.11.2015

nltk pos_tag is defined as:
from nltk.tag.perceptron import PerceptronTagger
def pos_tag(tokens, tagset=None):
    tagger = PerceptronTagger()
    return _pos_tag(tokens, tagset, tagger)

поэтому каждый вызов pos_tag создает экземпляр модуля perceptrontagger, который занимает большую часть времени вычислений. Вы можете сэкономить это время, напрямую вызвав tagger.tag самостоятельно:

from nltk.tag.perceptron import PerceptronTagger
tagger=PerceptronTagger()
sentence_pos = tagger.tag(word_tokenize(sentence))
person Abhiram Pappula    schedule 04.10.2016
comment
Есть ли способ уменьшить время для ner с помощью nltk - person Padegal Saigiriraj; 30.10.2019

Если вы ищете другой POS-теггер с высокой производительностью на Python, вы можете попробовать RDRPOSTagger. Например, при тегировании POS на английском языке скорость тегирования составляет 8 000 слов в секунду для однопоточной реализации на Python с использованием компьютера с процессором Core 2Duo 2,4 ГГц. Вы можете увеличить скорость тегирования, просто используя многопоточный режим. RDRPOSTagger обеспечивает очень конкурентоспособную точность по сравнению с современными тегировщиками и теперь поддерживает предварительно обученные модели для 40 языков. См. экспериментальные результаты в этой статье.

person NQD    schedule 20.11.2015