Подтвердить что ты не робот

Удаление стоп-слова с помощью NLTK

Я пытаюсь обработать введенный пользователем текст, удалив стоп-слова с помощью инструментария nltk, но при удалении по стоп-слова слова типа 'и', 'или', 'не' удаляются. Я хочу, чтобы эти слова присутствовали после процесса удаления после остановки, поскольку они являются операторами, которые необходимы для последующей обработки текста в качестве запроса. Я не знаю, какие слова могут быть операторами в текстовом запросе, и я также хочу удалить ненужные слова из моего текста.

4b9b3361

Ответ 1

Я предлагаю вам создать свой собственный список слов-операторов, которые вы выберете из списка. Наборы можно удобно вычесть, поэтому:

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

Затем вы можете просто проверить, есть ли слово in или not in набор, не полагаясь на то, являются ли ваши операторы частью списка заметок. Затем вы можете переключиться на другой список или добавить оператора.

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

Ответ 2

В NLTK имеется встроенный список заметок, состоящий из 2400 стоп-слов для 11 языков (Porter и др.), см. 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']

Я рекомендую посмотреть использование tf-idf для удаления стоп-слов, см. Влияние Stemming на частоту термина?

Ответ 3

@alvas отвечает, но это можно сделать быстрее. Предположим, что у вас есть documents: список строк.

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]

Обратите внимание, что из-за того, что здесь вы ищете в наборе (не в списке), скорость будет теоретически len(stop_words)/2 раз быстрее, что существенно, если вам нужно работать через многие документы.

Для 5000 документов размером около 300 слов разница составляет 1,8 секунды для моего примера и 20 секунд для @alvas.

P.S. в большинстве случаев вам нужно разделить текст на слова, чтобы выполнить некоторые другие задачи классификации, для которых используется tf-idf. Поэтому, скорее всего, было бы лучше использовать штокмер:

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

и использовать [porter.stem(i.lower()) for i in wordpunct_tokenize(doc) if i.lower() not in stop_words] внутри цикла.

Ответ 4

@alvas имеет хороший ответ. Но опять же это зависит от характера задачи, например, в вашем приложении вы хотите рассмотреть все conjunction, например. и, или, но, если, while и все determiner, например. a, some, most, every, no, как стоп-слова, считающие все остальные части речи законными, тогда вы можете захотеть изучить это решение, использующее тезисы Part of of Speech, чтобы отбросить слова, Проверить таблицу 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]