2014-09-30 12 views
15

Sto utilizzando una combinazione di NLTK e's CountVectorizer per le parole di derivazione e tokenizzazione.Combinazione di testo e rimozione della punteggiatura in NLTK e scikit-learn

Di seguito è riportato un esempio di utilizzo pianura del 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()) 

che stamperà

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

Ora, diciamo che voglio rimuovere parole di stop e arginare le parole. Una possibilità sarebbe quella di fare in questo modo:

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

che stampa:

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

Ma come potrei meglio sbarazzarsi dei caratteri di punteggiatura in questa seconda versione?

risposta

23

Esistono diverse opzioni, provare a rimuovere la punteggiatura prima della tokenizzazione. Ma questo significherebbe che 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 

Oppure provare a rimuovere la punteggiatura dopo tokenizzazione.

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 

a cura

Il codice qui sopra funziona ma è piuttosto lento perché è scorrendo lo stesso testo più volte:

  • volta per rimuovere la punteggiatura
  • La seconda volta di tokenize
  • Terza volta per arginare.

Se si dispone di più passaggi come la rimozione di cifre o rimuovere parole non significative o lettere minuscole, ecc

Sarebbe meglio grumo i passi insieme il più possibile, ecco più risposte migliori che è più efficiente se il vostro dati richiede più fasi di pre-lavorazione:

+0

Semplice ma efficace. Grazie! – Sebastian

+4

Si noti che il secondo non rileverà '...' o altri simboli di punteggiatura multi-carattere. –

+0

@FredFoo e altri: come valuti GENSIM e Scikit per le parole chiave estratte piuttosto i documenti semplici? Puoi rispondermi? http://stackoverflow.com/questions/40436110/rake-with-gensim –