2014-10-04 8 views
6

Po dokładnym profilowaniu mojego programu, udało mi się ustalić, że jest on spowalniany przez vectorizer.sklearn: Jak przyspieszyć vectorizer (np. Tfidfvectorizer)

Pracuję nad danymi tekstowymi, a dwie linie prostej wektoryzacji w wektorach Tfidf zajmują 99,2% całkowitego czasu potrzebnego do wykonania kodu.

Oto runnable przykład (ten pobierze plik szkoleniowy 3MB na dysku, pominięcie części urllib uruchomić na własnym próbki):

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

Próbowałem konwersji listę X_train w NP. array, ale nie było różnicy w wydajności.

+0

Możesz spróbować tego na http://codereview.stackexchange.com/. – matsjoyce

Odpowiedz

10

Nic więc dziwnego, że to NLTK że jest powolny:

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

Można to przyspieszyć stosując inteligentniejsze realizację Stemmer Snowball, np 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 to zestaw narzędzi nauczania . Projekt jest powolny, ponieważ jest zoptymalizowany pod kątem czytelności.

+0

To nie jest na Pythonie 3.6 :( – Hiding