Как можно очистить текст от шума (шумовые слова, пунктуация и пр.)?
Очистка текста от шума — это один из важнейших этапов предобработки в NLP. "Шум" включает в себя все элементы текста, которые не несут полезной смысловой нагрузки или могут негативно повлиять на последующий анализ. К таким элементам относятся: пунктуация, лишние пробелы, спецсимволы, стоп-слова, HTML-теги, ссылки, эмодзи, повторяющиеся буквы, цифры и пр.
Ниже приведён полный разбор методов очистки текста, с примерами и техническими аспектами.
1. Приведение к нижнему регистру (case normalization)
Все слова переводятся в lowercase, чтобы уменьшить количество уникальных токенов.
text = text.lower()
До: "The QUICK Brown Fox"
После: "the quick brown fox"
2. Удаление HTML-тегов
При работе с текстами из интернета часто присутствуют HTML-теги (<div>, <br>, <a> и др.). Они не несут смысловой информации.
from bs4 import BeautifulSoup
text = BeautifulSoup(text, "html.parser").get_text()
3. Удаление ссылок (URL)
Ссылки могут встречаться в социальных сетях, комментариях, чатах. Обычно их удаляют, если только не нужна информация о домене.
import re
text = re.sub(r'http\\S+|www\\S+|https\\S+', '', text)
4. Удаление эмодзи и спецсимволов
Эмодзи часто используются в соцсетях и могут быть удалены при необходимости. Для удаления:
import re
emoji_pattern = re.compile("\["
u"\\U0001F600-\\U0001F64F" # смайлы
u"\\U0001F300-\\U0001F5FF" # символы
u"\\U0001F680-\\U0001F6FF" # транспорт
u"\\U0001F1E0-\\U0001F1FF" # флаги
"\]+", flags=re.UNICODE)
text = emoji_pattern.sub(r'', text)
5. Удаление пунктуации
Знаки препинания (,, ., ?, !, -, : и др.) могут быть удалены или оставлены в зависимости от задачи. Например, в задачах синтаксического анализа — важны.
import string
text = text.translate(str.maketrans('', '', string.punctuation))
Также можно использовать регулярное выражение:
text = re.sub(r'\[^\\w\\s\]', '', text)
6. Удаление лишних пробелов и символов новой строки
text = re.sub(r'\\s+', ' ', text).strip()
7. Удаление стоп-слов
Стоп-слова — это часто встречающиеся слова (например, "и", "в", "на", "the", "is", "of"), которые обычно не несут информативной нагрузки в задачах классификации, тематического моделирования и др.
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
stop_words = set(stopwords.words('english'))
tokens = word_tokenize(text)
filtered_tokens = \[w for w in tokens if w not in stop_words\]
Для русского языка:
stop_words = set(stopwords.words('russian'))
Можно расширять список собственными словами (например, "читать", "смотреть", "узнать").
8. Удаление чисел
Если числа не являются значимыми (например, в новостях или чате), их можно удалить:
text = re.sub(r'\\d+', '', text)
Или удалить токены, содержащие только цифры:
tokens = \[word for word in tokens if not word.isdigit()\]
9. Стемминг или лемматизация
Это уже не просто очистка, но относится к нормализации текста — превращение слов к их базовой форме:
\# Стемминг
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
tokens = \[stemmer.stem(word) for word in tokens\]
\# Лемматизация
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
tokens = \[lemmatizer.lemmatize(word) for word in tokens\]
Для русского:
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
tokens = \[morph.parse(word)\[0\].normal_form for word in tokens\]
10. Обработка повторяющихся символов
В соцсетях или чатах часто встречаются выражения типа "прииивеет", "крууууууто". Можно нормализовать до одной или двух букв:
def reduce_lengthening(text):
return re.sub(r'(.)\\1{2,}', r'\\1\\1', text)
text = reduce_lengthening(text)
"прииииивеет" → "приивет"
11. Удаление специальных шаблонов
Можно очистить:
-
Упоминания: @username → re.sub(r'@\w+', '', text)
-
Хештеги: #topic → re.sub(r'#\w+', '', text)
-
Цитаты: > текст → re.sub(r'^>.*$', '', text, flags=re.MULTILINE)
12. Очистка неалфавитных символов
Оставить только буквы и пробелы:
text = re.sub(r'\[^a-zA-Zа-яА-ЯёЁ\\s\]', '', text)
13. Очистка по частям речи (опционально)
Можно удалить, например, междометия, союзы и предлоги на основе POS-тегов:
import nltk
from nltk import pos_tag
tokens = nltk.word_tokenize(text)
tagged = pos_tag(tokens)
cleaned = \[word for word, tag in tagged if tag not in \['IN', 'CC', 'UH'\]\]
14. Удаление коротких или длинных слов
Иногда удаляют слова короче 3 символов:
tokens = \[word for word in tokens if len(word) > 2\]
Пример пайплайна очистки
import re
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
import string
nltk.download('punkt')
nltk.download('stopwords')
def clean_text(text):
text = text.lower()
text = re.sub(r"http\\S+|www\\S+", "", text)
text = re.sub(r"<.\*?>", "", text)
text = re.sub(r"\\d+", "", text)
text = text.translate(str.maketrans("", "", string.punctuation))
text = re.sub(r"\\s+", " ", text).strip()
tokens = word_tokenize(text)
stop_words = set(stopwords.words("english"))
tokens = \[w for w in tokens if w not in stop_words\]
return tokens
Дополнительные инструменты
-
spaCy — предоставляет токенизацию, удаление стоп-слов, POS-теггинг, NER и лемматизацию в одном пайплайне
-
TextBlob — удобный API для быстрой предобработки
-
clean-text — библиотека с готовыми функциями: удаления URL, HTML, эмодзи, чисел и т.п.
-
emoji — для обнаружения/удаления эмодзи
-
langdetect — для фильтрации по языку (например, исключить неанглийский текст)
Каждый из этапов очистки можно включать или исключать в зависимости от специфики задачи: анализ тональности, тематическое моделирование, чат-бот, генерация текста, NER и т.д. Важно соблюдать баланс между удалением шума и сохранением информации.