2014-09-30 3 views
15

Ich verwende eine Kombination von NLTK und scikit-learnCountVectorizer für Stemming Wörter und Tokenization.Kombinieren von Text Stemming und Entfernen von Satzzeichen in NLTK und Scikit-lernen

Im Folgenden ist ein Beispiel für die Ebene Nutzung des CountVectorizer:

from sklearn.feature_extraction.text import CountVectorizer 

vocab = ['The swimmer likes swimming so he swims.'] 
vec = CountVectorizer().fit(vocab) 

sentence1 = vec.transform(['The swimmer likes swimming.']) 
sentence2 = vec.transform(['The swimmer swims.']) 

print('Vocabulary: %s' %vec.get_feature_names()) 
print('Sentence 1: %s' %sentence1.toarray()) 
print('Sentence 2: %s' %sentence2.toarray()) 

Welche

Vocabulary: ['he', 'likes', 'so', 'swimmer', 'swimming', 'swims', 'the'] 
Sentence 1: [[0 1 0 1 1 0 1]] 
Sentence 2: [[0 0 0 1 0 1 1]] 

Jetzt druckt, sagen wir, ich Stoppwörter entfernen möchten, und die Worte stammen. Eine Möglichkeit wäre, es zu tun, wie so:

from nltk import word_tokenize   
from nltk.stem.porter import PorterStemmer 

####### 
# based on http://www.cs.duke.edu/courses/spring14/compsci290/assignments/lab02.html 
stemmer = PorterStemmer() 
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) 
    stems = stem_tokens(tokens, stemmer) 
    return stems 
######## 

vect = CountVectorizer(tokenizer=tokenize, stop_words='english') 

vect.fit(vocab) 

sentence1 = vect.transform(['The swimmer likes swimming.']) 
sentence2 = vect.transform(['The swimmer swims.']) 

print('Vocabulary: %s' %vect.get_feature_names()) 
print('Sentence 1: %s' %sentence1.toarray()) 
print('Sentence 2: %s' %sentence2.toarray()) 

Welche druckt:

Vocabulary: ['.', 'like', 'swim', 'swimmer'] 
Sentence 1: [[1 1 1 1]] 
Sentence 2: [[1 0 1 1]] 

Aber wie würde ich am besten loszuwerden, die Satzzeichen in dieser zweiten Version?

Antwort

23

Es gibt mehrere Optionen, versuchen Sie, die Interpunktion vor der Tokenisierung zu entfernen. Aber das würde bedeuten, dass don't ->dont

import string 

def tokenize(text): 
    text = "".join([ch for ch in text if ch not in string.punctuation]) 
    tokens = nltk.word_tokenize(text) 
    stems = stem_tokens(tokens, stemmer) 
    return stems 

Oder versuchen Interpunktion nach tokenization entfernen.

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

EDITED

Der obige Code funktioniert, aber es ist ziemlich langsam, weil es mehrfach durch den gleichen Text ist Looping:

  • Einmal Interpunktion
  • zum zweiten Mal entfernen tokenize
  • Das dritte Mal zu stemmen.

Wenn Sie mehr Schritte sind wie Stellen zu entfernen oder Stoppwörter oder Kleinschreibung zu entfernen usw.

Es wäre besser, die Schritte zusammen, so viel wie möglich einen Topf zu werfen, hier einige bessere Antworten, die effizienter ist, wenn Ihr Daten erfordert mehr Vorverarbeitungsschritte:

+0

Einfach aber effektiv. Vielen Dank! – Sebastian

+4

Beachten Sie, dass die zweite Option keine '...' oder andere Mehrzeichen-Interpunktionssymbole abfängt. –

+0

@FredFoo und andere: Wie bewerten Sie GENSIM und Scikit für die extrahierten Keywords eher die einfachen Dokumente? Kannst du mir antworten? http://stackoverflow.com/questions/40436110/rake-with-gensim –

Verwandte Themen