2015-11-12 10 views
5

Sto usando nltk per generare n-grammi dalle frasi rimuovendo prima le parole di stop date. Tuttavia, nltk.pos_tag() è estremamente lento e richiede fino a 0,6 secondi sulla mia CPU (Intel i7).POS-Tagger è incredibilmente lento

L'output:

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

Il codice:

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) 

è davvero questo che rallentano o sto facendo qualcosa di sbagliato qui?

+0

puoi pubblicare il testo che hai inserito? Qual è la specifica della tua macchina (velocità della CPU e RAM)? Ti stai connettendo a una nuvola e come stai cronometrando la funzione? Vedi anche http://stackoverflow.com/questions/33558836/pos-tagging-using-nltk-takes-time – alvas

+1

@alvas È un Intel i7 (indicato nella domanda). 16 GB di RAM. No, non è nel cloud è locale. Puoi vedere nel mio esempio di codice come lo faccio ora. – displayname

+0

È necessario parallelizzare la soluzione se si dispone di un set di dati enorme. Altrimenti (se puoi tenere le frasi taggate nella RAM), raccogli semplicemente tutte le frasi taggate e poi fai il filtro. – alvas

risposta

5

Usa pos_tag_sents per la codifica più frasi:

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

Molto bello! L'uso di 'pos_tag_sents()' migliora molto le prestazioni. È strano perché questo è il caso. Sembra che pos_tag() ripeta un'inizializzazione o qualcosa del genere. – displayname

+0

È una domanda con una risposta piuttosto lunga, ma se si fa una domanda separata su come e perché è più veloce, qualcuno potrebbe rispondere. se nessuno risponde, risponderò quando sarò libero domani sera =) – alvas

+0

[Ci vai] (http://stackoverflow.com/questions/33829160/why-is-pos-tag-so-painfully -slow-and-can-this-be-avoided);) – displayname

0

Se siete alla ricerca di un altro tagger POS con performance veloci in Python, si potrebbe desiderare di provare RDRPOSTagger. Ad esempio, sulla codifica POS in inglese, la velocità di codifica è di 8K parole/secondo per un'implementazione a thread singolo in Python, utilizzando un computer di Core 2Duo a 2,4 GHz. Puoi ottenere una velocità di tag più veloce semplicemente utilizzando la modalità multi-thread. RDRPOSTagger ottiene precisioni molto competitive rispetto ai tagger più avanzati e ora supporta modelli pre-formati per 40 lingue. Visualizza i risultati sperimentali 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) 

in modo che ogni chiamata al pos_tag un'istanza del modulo di perceptrontagger che prende gran parte del time.You calcolo può salvare questa volta chiamando direttamente tagger.tag te stesso come:

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

grazie, questo è molto più veloce! – liang