2014-10-04 6 views
6

Nachdem ich mein Programm gründlich profiliert habe, konnte ich feststellen, dass es vom Vektorisierer verlangsamt wird.sklearn: Wie man einen Vektorisierer beschleunigt (zB Tfidfvectorizer)

Ich arbeite an Textdaten, und zwei Zeilen der einfachen TFIDF-Unigram-Vektorisierung nimmt 99,2% der Gesamtzeit auf, die der Code zur Ausführung benötigt.

Hier ist ein lauffähiges Beispiel (dies wird die urllib Teile eine 3mb Trainingsdatei auf Ihrer Festplatte, lassen Sie herunterladen auf Ihrem eigenen Beispiel auszuführen):

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

Ich versuchte X_train in eine np die Liste zu konvertieren. Array, aber es gab keinen Unterschied in der Leistung.

+0

Sie könnten dies auf http://codereview.stackexchange.com/ versuchen. – matsjoyce

Antwort

10

Es überrascht nicht, ist es NLTK, die langsam ist:

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

Sie können dies beschleunigen, indem eine intelligentere Umsetzung des Schneeball stemmer unter Verwendung zB 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 ist ein Lehr Toolkit . Es ist langsam im Design, weil es für die Lesbarkeit optimiert ist.

+0

Dies ist nicht auf Python 3.6 :( – Hiding

Verwandte Themen