2014-10-04 3 views
6

Dopo aver profilato il mio programma in modo approfondito, sono stato in grado di individuare che è stato rallentato dal vettore.sklearn: Come velocizzare un vettore (es. Tfidfvectorizer)

Sto lavorando a dati di testo e due righe di semplice vettorizzazione ungram di tfidf occupano il 99,2% del tempo totale che il codice impiega per eseguire.

Ecco un esempio eseguibile (questo verrà scaricato un file di allenamento 3 MB sul disco, omettere le parti urllib per l'esecuzione sul proprio campione):

##################################### 
# Loading Data 
##################################### 
import urllib 
from sklearn.feature_extraction.text import TfidfVectorizer 
import nltk.stem 
raw = urllib.urlopen("https://s3.amazonaws.com/hr-testcases/597/assets/trainingdata.txt").read() 
file = open("to_delete.txt","w").write(raw) 
### 
def extract_training(): 
    f = open("to_delete.txt") 
    N = int(f.readline()) 
    X = [] 
    y = [] 
    for i in xrange(N): 
     line = f.readline() 
     label,text = int(line[0]), line[2:] 
     X.append(text) 
     y.append(label) 
    return X,y 
X_train, y_train = extract_training()  
############################################# 
# Extending Tfidf to have only stemmed features 
############################################# 
english_stemmer = nltk.stem.SnowballStemmer('english') 

class StemmedTfidfVectorizer(TfidfVectorizer): 
    def build_analyzer(self): 
     analyzer = super(TfidfVectorizer, self).build_analyzer() 
     return lambda doc: (english_stemmer.stem(w) for w in analyzer(doc)) 

tfidf = StemmedTfidfVectorizer(min_df=1, stop_words='english', analyzer='word', ngram_range=(1,1)) 
############################################# 
# Line below takes 6-7 seconds on my machine 
############################################# 
Xv = tfidf.fit_transform(X_train) 

Ho provato a convertire la lista X_train in un np. array ma non c'era differenza nelle prestazioni.

+0

Si può provare su http://codereview.stackexchange.com/. – matsjoyce

risposta

10

Non sorprende, è NLTK che è lento:

>>> tfidf = StemmedTfidfVectorizer(min_df=1, stop_words='english', analyzer='word', ngram_range=(1,1)) 
>>> %timeit tfidf.fit_transform(X_train) 
1 loops, best of 3: 4.89 s per loop 
>>> tfidf = TfidfVectorizer(min_df=1, stop_words='english', analyzer='word', ngram_range=(1,1)) 
>>> %timeit tfidf.fit_transform(X_train) 
1 loops, best of 3: 415 ms per loop 

È possibile accelerare questo utilizzando una intelligente applicazione della Stemmer Palla di neve, ad esempio, PyStemmer:

>>> import Stemmer 
>>> english_stemmer = Stemmer.Stemmer('en') 
>>> class StemmedTfidfVectorizer(TfidfVectorizer): 
...  def build_analyzer(self): 
...   analyzer = super(TfidfVectorizer, self).build_analyzer() 
...   return lambda doc: english_stemmer.stemWords(analyzer(doc)) 
...  
>>> tfidf = StemmedTfidfVectorizer(min_df=1, stop_words='english', analyzer='word', ngram_range=(1,1)) 
>>> %timeit tfidf.fit_transform(X_train) 
1 loops, best of 3: 650 ms per loop 

NLTK è un toolkit di insegnamento . È lento in base alla progettazione, perché è ottimizzato per la leggibilità.

+0

Questo non è su Python 3.6 :( – Hiding