Combinación de texto derivado y eliminación de puntuación en NLTK y scikit-learn

Estoy usando una combinación de scikit-learn y scikit-learn para CountVectorizer palabras y tokenización.

A continuación se muestra un ejemplo del uso simple 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()) 

Que se imprimirá

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

Ahora, digamos que quiero eliminar las palabras clave y eliminarlas. Una opción sería hacerlo así:

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

Que imprime:

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

    Pero, ¿cuál es la mejor forma de deshacerme de los caracteres de puntuación en esta segunda versión?

    Related of "Combinación de texto derivado y eliminación de puntuación en NLTK y scikit-learn"

    Hay varias opciones, intente eliminar la puntuación antes de la tokenización. Pero esto significaría que 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 

    O intente eliminar la puntuación después de la tokenización.

     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 

    Editado

    El código anterior funcionará pero es bastante lento porque se repite en el mismo texto varias veces:

    • Una vez para eliminar la puntuación.
    • Segunda vez para tokenizar
    • Tercera vez para detener.

    Si tiene más pasos como eliminar dígitos o eliminar palabras clave o hacer minúsculas, etc.

    Sería mejor agrupar los pasos lo más posible, aquí hay varias respuestas mejores que son más eficientes si sus datos requieren más pasos de preprocesamiento: