2017-11-22 7 views
1

Erste Frage, tut mir leid, wenn ich etwas vermasseln.Beschleunigen der Vektorisierung in sklearn

Ich mache ein Klassifizierungsprojekt mit 1600 einzigartigen Textdokumenten über 90 Etiketten. Viele dieser Dokumente sind Forschungsarbeiten, Sie können sich also vorstellen, dass der Funktionsumfang ziemlich groß ist - weit über eine Million.

Mein Problem ist, dass die Vektorisierung dauert für immer. Ich verstehe, dass es mit meinen Daten nicht schnell gehen wird, aber die Zeit, die es braucht, wird unpraktisch. Ich habe den Rat von der ersten Antwort auf this question genommen und es scheint nicht geholfen zu haben - ich stelle mir vor, dass die Optimierungen, die der Antworter vorschlägt, bereits in scikit-learn integriert sind.

Hier ist mein Code, die angepasst dämmt vectorizer Funktionen:

%%timeit 

vect = StemmedCountVectorizer(min_df=3, max_df=0.7, max_features=200000, tokenizer=tokenize, 
     strip_accents='unicode', analyzer='word', token_pattern=r'\w{1,}', 
     ngram_range=(1, 3), stop_words='english') 

vect.fit(list(xtrain) + list(xvalid)) 
xtrain_cv = vect.transform(xtrain) 
xvalid_cv = vect.transform(xvalid) 

Die tokenizer Referenzen diese Funktion:

stemmer = SnowballStemmer('english') 

def stem_tokens(tokens, stemmer): 
    stemmed = [] 
    for item in tokens: 
     stemmed.append(stemmer.stem(item)) 
    return stemmed 

def tokenize(text): 
    tokens = nltk.word_tokenize(text) 
    tokens = [i for i in tokens if i not in string.punctuation] 
    tokens = [i for i in tokens if all(j.isalpha() or j in string.punctuation for j in i)] 
    tokens = [i for i in tokens if '/' not in i] 
    stems = stem_tokens(tokens, stemmer) 
    return stems 

Der %%timeit Bericht:

24min 16s ± 28.2 s per loop (mean ± std. dev. of 7 runs, 1 loop each) 

Ist dort etwas, das ist offensichtlich verlangsamt mich? Jede offensichtliche Ineffizienz wäre gut zu wissen. Ich denke darüber nach, meinen N-Gramm-Bereich auf (1,2) zu reduzieren, da ich nicht glaube, dass ich zu viele nützliche 3-Gramm-Funktionen bekomme, aber außerdem bin ich mir nicht sicher, was ich sonst tun soll.

+0

@WhatsThePoint - was meinst du mit "die andere Lösung"? Wenn Sie die Standardvektorisierer referenzieren, sind sie auch extrem langsam. Das hat meine ursprüngliche Suche nach Optimierungslösungen motiviert. Leider habe ich gerade angefangen, '%% timeit' zu verwenden, so dass ich keinen Zeitbericht habe, aber ich führe es jetzt aus. –

+0

der Posted Stack Overflow-Link – WhatsThePoint

+0

Oh, gut, das ist der Code, den ich derzeit verwende, wenn ich 'StemmedCountVectorizer()' aufrufen, aber mein Problem ist, dass es immer noch sehr langsam ist. Ich tue sowohl einen countvectorizer als auch einen tfidfvectorizer zu Testzwecken, und 'StemmedCountVectorizer()' ist fertig, aber 'StemmedTfidfVectorizer()' lief immer noch, als ich heute Morgen aufwachte, was bedeutete, dass es mindestens drei Stunden dauerte. –

Antwort

0

1600 Textdokumente ist nicht wirklich so groß, so sollte es viel schneller sein. Einige Empfehlungen:

1) Um Ihren Code zu profilieren, verwenden Sie cProfile and ptats. Sie werden sehen, welche genauen Schritte langsam sind.

2) N-Gramme haben eine enorme Komplexität. Bi-Grams sind in der Regel in Ordnung, Tri-Grams beginnen sehr umständlich. Verwenden Sie eine "intelligentere" Lösung. Warum nicht die Gensim phraser?

3) mit in Operator nicht gut mit Listen (weil es jedes Element der Liste testet), aber gut mit Sätzen (wegen der zugrunde liegenden Hash-Funktion). Sie sollten Zeichenfolgen wie string.punctuation als Listen betrachten. Konvertiere es einfach in ein Set.

4) Factorize Ihre tokenize Funktion (mehrere Schleifen auf token) wenn Sie können.

5) Wenn es nicht schnell genug ist, verwenden Sie Multi Threading.