Исключение стоп-слов при обработке естественного языка
Зачем удалять стоп-слова при обработке текста
Стоп-слова (stop words) - это часто встречающиеся слова, которые обычно не несут смысловой нагрузки для анализа текста (предлоги, союзы, местоимения и т.п.). Их удаление позволяет уменьшить размерность данных и повысить качество моделей NLP. В Python существует несколько способов работы со стоп-словами, от встроенных библиотек до ручного составления списков.
Как удалить стоп-слова с помощью библиотеки NLTK?
Библиотека NLTK предоставляет готовый набор стоп-слов для многих языков. Для русского языка используется следующий код:
import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = set(stopwords.words('russian'))
text = "Этот пример содержит несколько стоп-слов: и, в, на, с"
words = text.lower().split()
filtered_words = [word for word in words if word not in stop_words]
print(filtered_words)библиотека nlp python (библиотека nlp в python)
Пояснение: сначала загружаются стоп-слова, затем текст приводится к нижнему регистру и разбивается на слова. Список stop_words преобразуется в множество для ускорения проверки. Только те слова, которые не входят в множество, остаются в результатах.
Возможные проблемы:
- Необходимо предварительно скачать корпус командой nltk.download('stopwords'). Если этого не сделать - возникнет LookupError.
- Стоп-слова NLTK не включают пунктуацию и цифры - их нужно удалять отдельно.
- Регистр слов: без .lower() слова «В» и «в» будут считаться разными.
Вариант с SpaCy: как получить встроенные стоп-слова и атрибут is_stop?
SpaCy содержит модели с предобученными стоп-словами и быстрым токенизатором. У каждого токена есть атрибут is_stop.
import spacy
nlp = spacy.load('ru_core_news_sm')
doc = nlp("Москва - столица России и крупный город")
filtered = [token.text for token in doc if not token.is_stop]
print(filtered)библиотека spacy python (библиотека spacy в python)
Пояснение: загружается русская модель, документ обрабатывается, и из списка токенов выбираются только те, у которых is_stop равен False. Модель также удаляет знаки препинания, так как они тоже могут быть помечены как стоп.
Возможные проблемы:
- Модель spacy нужно загрузить отдельно (python -m spacy download ru_core_news_sm).
- Список стоп-слов можно расширить через nlp.Defaults.stop_words.add('новое_слово').
Вариант с Gensim: функция remove_stopwords
Gensim предлагает простую функцию remove_stopwords для быстрой очистки текста.
from gensim.parsing.preprocessing import remove_stopwords
text = "эта система обрабатывает текст и удаляет стоп-слова"
clean_text = remove_stopwords(text)
print(clean_text)
Python текст перевод (перевод текста с помощью python)
Пояснение: функция принимает строку и удаляет все стоп-слова (по умолчанию английские). Для русского языка потребуется передать свой список.
Возможные проблемы:
- По умолчанию используются стоп-слова английского языка. Чтобы использовать русские, нужно установить язык через stopwords.ensure_loaded('russian') (в версиях до 4.0).
- Функция не удаляет пунктуацию.
Вариант с CountVectorizer из sklearn: стоп-слова при создании матрицы термов
При построении мешка слов можно сразу исключить стоп-слова, указав параметр stop_words.
from sklearn.feature_extraction.text import CountVectorizer
corpus = ["этот текст содержит много стоп-слов", "другой документ без лишних слов"]
vectorizer = CountVectorizer(stop_words='russian')
X = vectorizer.fit_transform(corpus)
print(vectorizer.get_feature_names_out())определить язык слова python (определение языка слова в python)
Пояснение: параметр stop_words='russian' автоматически загружает список стоп-слов из NLTK (если он установлен) и исключает их из матрицы. Полученные признаки не содержат стоп-слов.
Возможные проблемы:
- Требуется установленный NLTK с загруженным корпусом stopwords.
- Если язык не указан, используется английский.
Вариант с собственным списком стоп-слов: полный контроль над фильтрацией
Иногда нужно задать свой набор слов (например, для специфической предметной области).
custom_stop_words = {'этот', 'тот', 'самый', 'весь', 'каждый'}
text = "Каждый студент должен сдать этот экзамен"
words = text.lower().split()
filtered = [w for w in words if w not in custom_stop_words]
print(filtered)Пояснение: создаётся множество пользовательских стоп-слов, и при фильтрации они удаляются. Такой подход даёт максимальную гибкость, но требует ручного составления списка.
Возможные проблемы:
- Необходимо учесть все нужные словоформы.
- Без нормализации (стемминг, лемматизация) слова «студент» и «студенты» будут восприниматься отдельно.
Расширенные примеры работы со стоп-словами
Пример 1: NLTK с несколькими языками и удалением пунктуации
import nltk
from nltk.corpus import stopwords
import string
nltk.download('stopwords')
# Загружаем стоп-слова для русского и английского языков
stop_words = set(stopwords.words('russian') + stopwords.words('english'))
# Добавляем пунктуацию как стоп-символы
stop_words.update(string.punctuation)
text = "Hello! Это пример текста с английскими и русскими стоп-словами, такими как: and, the, в, на."
words = text.lower().split()
filtered = [word for word in words if word not in stop_words]
print('Результат:', filtered)Результат: ['hello!', 'пример', 'текста', 'английскими', 'русскими', 'стоп-словами,', 'такими', 'как:', 'and,', 'the,', 'в,', 'на.']
Обратите внимание: пунктуация, прикреплённая к словам (например, 'hello!'), не удалилась - для этого нужна дополнительная очистка. Пример демонстрирует объединение стоп-слов разных языков.
Пример 2: SpaCy с лемматизацией и удалением стоп-слов
import spacy
nlp = spacy.load('ru_core_news_sm')
text = "Лемматизация помогает приводить слова к начальной форме"
doc = nlp(text)
filtered_lemmas = [token.lemma_ for token in doc if not token.is_stop and not token.is_punct]
print('Леммы без стоп-слов:', filtered_lemmas)Леммы без стоп-слов: ['лемматизация', 'помогать', 'приводить', 'слово', 'к', 'начальный', 'форма']
Здесь не только удаляются стоп-слова, но и применяется лемматизация, что особенно полезно для анализа текстов с разными грамматическими формами.
Пример 3: Использование собственного списка с регулярными выражениями
import re
custom_stop = {'очень', 'весьма', 'крайне'}
text = "Это очень интересная и весьма полезная статья"
# Удаляем стоп-слова с учётом границ слов
pattern = r'\b(?:' + '|'.join(re.escape(w) for w in custom_stop) + r')\b'
clean_text = re.sub(pattern, '', text, flags=re.IGNORECASE)
clean_text = re.sub(r'\s+', ' ', clean_text).strip()
print('Результат:', clean_text)Результат: Это интересная и полезная статья
Регулярное выражение позволяет учитывать целые слова (границы \b) и игнорировать регистр. Однако такой подход может быть медленнее при большом списке стоп-слов.
Пример 4: Удаление стоп-слов в Pandas DataFrame
import pandas as pd
from nltk.corpus import stopwords
stop_words = set(stopwords.words('russian'))
df = pd.DataFrame({'text': ['в этом предложении есть стоп-слова', 'другой пример без стоп']})
def remove_stopwords(text):
return ' '.join([word for word in text.lower().split() if word not in stop_words])
df['cleaned'] = df['text'].apply(remove_stopwords)
print(df)text cleaned 0 в этом предложении есть стоп-слова предложении стоп-слова 1 другой пример без стоп другой пример стоп
Метод apply применяет функцию очистки к каждому тексту в колонке. Это удобно для предобработки данных перед машинным обучением.
Пример 5: Оптимизация с использованием frozenset и генераторов
import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')
stop_words = frozenset(stopwords.words('russian')) # неизменяемое множество для потенциального хеширования
text = "оптимизация множества позволяет быстрее проверять вхождение"
filtered_gen = (word for word in text.lower().split() if word not in stop_words)
result = ' '.join(filtered_gen)
print('Результат:', result)Результат: оптимизация множества позволяет быстрее проверять вхождение
Использование генератора вместо списка экономит память, а frozenset гарантирует неизменность набора стоп-слов.