Eliminación de palabras clave con NLTK

Estoy tratando de procesar un texto ingresado por un usuario eliminando palabras clave que usan el kit de herramientas nltk, pero con palabras eliminadas de palabras detenidas se eliminan las palabras como ‘y’, ‘o’, ‘no’. Quiero que estas palabras estén presentes después del proceso de eliminación de palabras de parada, ya que son operadores que se requieren para el procesamiento posterior del texto como consulta. No sé cuáles son las palabras que pueden ser operadores en la consulta de texto, y también quiero eliminar las palabras innecesarias de mi texto.

Le sugiero que cree su propia lista de palabras de operador que saca de la lista de palabras clave. Los conjuntos se pueden restar convenientemente, por lo que:

operators = set(('and', 'or', 'not')) stop = set(stopwords...) - operators 

Luego, simplemente puede probar si una palabra está o not in el conjunto sin depender de si sus operadores son parte de la lista de palabras clave. Luego puede cambiar a otra lista de palabras clave o agregar un operador.

 if word.lower() not in stop: # use word 

Hay una lista de palabras de parada incorporada en NLTK compuesta de 2,400 palabras de parada para 11 idiomas (Porter et al), consulte http://nltk.org/book/ch02.html

 >>> from nltk import word_tokenize >>> from nltk.corpus import stopwords >>> stop = set(stopwords.words('english')) >>> sentence = "this is a foo bar sentence" >>> print([i for i in sentence.lower().split() if i not in stop]) ['foo', 'bar', 'sentence'] >>> [i for i in word_tokenize(sentence.lower()) if i not in stop] ['foo', 'bar', 'sentence'] 

Recomiendo considerar el uso de tf-idf para eliminar palabras clave, consulte Efectos de la derivación en el término frecuencia.

La respuesta de @alvas hace el trabajo pero puede hacerse mucho más rápido. Suponiendo que tiene documents : una lista de cadenas.

 from nltk.corpus import stopwords from nltk.tokenize import wordpunct_tokenize stop_words = set(stopwords.words('english')) stop_words.update(['.', ',', '"', "'", '?', '!', ':', ';', '(', ')', '[', ']', '{', '}']) # remove it if you need punctuation for doc in documents: list_of_words = [i.lower() for i in wordpunct_tokenize(doc) if i.lower() not in stop_words] 

Tenga en cuenta que debido al hecho de que aquí está buscando en un conjunto (no en una lista) la velocidad sería teóricamente len(stop_words)/2 veces más rápida, lo cual es importante si necesita operar a través de muchos documentos.

Para 5000 documentos de aproximadamente 300 palabras cada uno, la diferencia es entre 1.8 segundos para mi ejemplo y 20 segundos para @alvas.

PD: en la mayoría de los casos, debe dividir el texto en palabras para realizar otras tareas de clasificación para las que se utiliza tf-idf. Así que lo más probable es que también sea mejor usar stemmer:

 from nltk.stem.porter import PorterStemmer porter = PorterStemmer() 

y para usar [porter.stem(i.lower()) for i in wordpunct_tokenize(doc) if i.lower() not in stop_words] dentro de un bucle.

@alvas tiene una buena respuesta. Pero nuevamente, depende de la naturaleza de la tarea, por ejemplo, en su aplicación desea considerar todas las conjunction por ejemplo , y, o, pero, si, while y todo determiner por ejemplo , a, algo, casi, todo, no como palabras de parada considerando que todas las otras partes del discurso son legítimas, entonces es posible que desee buscar en esta solución que utiliza el Conjunto de tags de parte del discurso para descartar palabras, consulte la tabla 5.1 :

 import nltk STOP_TYPES = ['DET', 'CNJ'] text = "some data here " tokens = nltk.pos_tag(nltk.word_tokenize(text)) good_words = [w for w, wtype in tokens if wtype not in STOP_TYPES] 

Puede usar string.punctuation con la lista de palabras clave NLTK incorporadas:

 from nltk.tokenize import word_tokenize, sent_tokenize from nltk.corpus import stopwords from string import punctuation words = tokenize(text) wordsWOStopwords = removeStopWords(words) def tokenize(text): sents = sent_tokenize(text) return [word_tokenize(sent) for sent in sents] def removeStopWords(words): customStopWords = set(stopwords.words('english')+list(punctuation)) return [word for word in words if word not in customStopWords] 

NLTK stopwords lista completa