2015-11-12 5 views
5

Ich verwende nltk, um N-Gramm aus Sätzen zu generieren, indem zuerst gegebene Stopwörter entfernt werden. Allerdings ist nltk.pos_tag() extrem langsam und dauert bis zu 0,6 Sekunden auf meiner CPU (Intel i7).POS-Tagger ist unglaublich langsam

Der Ausgang:

['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 

Der Code:

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) 

Ist das wirklich so langsam oder mache ich etwas falsch hier?

+0

Können Sie den Text schreiben, dass hast du eingabe? Was ist die Spezifikation Ihrer Maschine (CPU-Geschwindigkeit und RAM)? Verbinden Sie sich mit einer Cloud und wie wird die Funktion getimed? Siehe auch http://stackoverflow.com/questions/33558836/pos-tagging-using-nltk-takes-time – alvas

+1

@alvas Es ist ein Intel i7 (in der Frage angegeben). 16 GB RAM. Nein, es ist nicht in der Cloud, es ist lokal. Sie können in meinem Codebeispiel sehen, wie ich es zeitlich passe. – displayname

+0

Sie müssen Ihre Lösung parallelisieren, wenn Sie einen großen Datensatz haben. Andernfalls (wenn Sie die getaggten Sätze im RAM halten können), sammeln Sie einfach alle markierten Sätze und machen Sie anschließend den Filter. – alvas

Antwort

5

Verwenden pos_tag_sents zum Markieren mehrerer Sätze:

>>> 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 
+0

Sehr nett! Die Verwendung von 'pos_tag_sents()' verbessert die Leistung sehr. Es ist seltsam, warum das so ist. Es scheint, dass 'pos_tag()' eine Initialisierung oder etwas Ähnliches wiederholt. – displayname

+0

Es ist eine Frage mit einer ziemlich langen Antwort, aber wenn Sie eine separate Frage stellen, wie und warum es schneller ist, könnte jemand antworten. wenn niemand antwortet, antworte ich, wenn ich morgen Abend frei bin. =) – alvas

+0

[Da gehts] (http://stackoverflow.com/questions/33829160/why-is-post-tag-so-maessig -slow-and-can-this-be-vermieden werden;) – displayname

0

Wenn Sie nach einem anderen POS-Tagger mit schnellen Auftritten in Python suchen, könnten Sie RDRPOSTagger ausprobieren möchten. Beim englischen POS-Tagging beträgt die Tagging-Geschwindigkeit z. B. 8K Wörter/Sekunde für eine Implementierung mit einem Thread in Python, wobei ein Computer mit Core 2Duo 2.4GHz verwendet wird. Sie können eine schnellere Tagging-Geschwindigkeit erzielen, indem Sie einfach den Multithread-Modus verwenden. RDRPOSTagger erzielt sehr wettbewerbsfähige Genauigkeiten im Vergleich zu modernen Taggern und unterstützt jetzt vortrainierte Modelle für 40 Sprachen. Siehe Versuchsergebnisse in this paper.

4
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) 

so jeder Aufruf pos_tag instanziiert das perceptrontagger-Modul, das einen Großteil der Berechnung time.You nimmt sich direkt durch den Aufruf tagger.tag diese Zeit sparen können als:

from nltk.tag.perceptron import PerceptronTagger 
tagger=PerceptronTagger() 
sentence_pos = tagger.tag(word_tokenize(sentence)) 
+0

danke, das ist viel schneller! – liang