Нормализация: регистр, пунктуация, стоп-слова, стемминг
Нормализация уменьшает «шум» в тексте, чтобы модель видела суть, а не случайные различия в написании.
Нормализация текста — приведение слов к единому каноническому виду, чтобы варианты написания одного и того же не считались разными токенами.
Зачем нормализовать
Для машины «Привет», «привет» и «привет!» — три разные строки. Для задачи это обычно одно и то же слово. Нормализация убирает лишние различия: регистр, пунктуацию, незначащие слова, формы слова. Чем меньше «случайного» в данных, тем легче модели найти настоящую закономерность.
Нижний регистр и пунктуация
Два самых дешёвых и частых шага: привести всё к нижнему регистру и убрать знаки препинания (если они не важны для задачи).
import re
text = "Привет, МИР!! Как Дела?"
text = text.lower() # нижний регистр
text = re.sub(r"[^\w\s]", "", text) # убрать пунктуацию
tokens = text.split()
print(tokens)
Вывод:
['привет', 'мир', 'как', 'дела']
Стоп-слова
Стоп-слова — очень частые служебные слова («и», «в», «не», «что», «как»), которые почти не несут смысла для многих задач, но засоряют статистику. В классических методах (bag-of-words, TF-IDF) их часто удаляют.
stop_words = {"и", "в", "на", "с", "что", "как", "это", "а", "но"}
text = "это очень хороший и в меру дорогой телефон"
tokens = [w for w in text.split() if w not in stop_words]
print("Было слов:", len(text.split()))
print("Осталось:", tokens)
Вывод:
Было слов: 8 Осталось: ['очень', 'хороший', 'меру', 'дорогой', 'телефон']
Важно: для некоторых задач стоп-слова критичны. В анализе тональности «не» — ключевое слово («не понравилось»), и удалять его нельзя. Решение зависит от задачи.
Стемминг и лемматизация
Это два способа свести разные формы слова к одной. Они борются с той самой морфологической проблемой из урока о трудностях языка.
- Стемминг — грубое отрезание окончаний по правилам. «бегать», «бегает», «бегу» → «бег». Быстро, но топорно: результат не всегда настоящее слово.
- Лемматизация — приведение к словарной форме (лемме) с учётом грамматики. «бежал», «бегу», «бежит» → «бежать». Точнее, но требует словаря и морфологического анализатора.
Покажем игрушечный стеммер, который просто отрезает несколько типичных русских окончаний — чтобы прочувствовать идею (настоящие стеммеры сложнее).
def naive_stem(word):
# суффиксы перебираем от длинных к коротким
for suffix in ["ает", "ать", "ыми", "ого", "ему", "ешь", "у", "ю", "ть", "ла", "ли", "ет", "ут", "и", "а", "о", "е"]:
if word.endswith(suffix) and len(word) - len(suffix) >= 3:
return word[: -len(suffix)]
return word
for w in ["бегает", "бегу", "бегать", "красивого", "красивыми"]:
print(w, "->", naive_stem(w))
Вывод:
бегает -> бег бегу -> бег бегать -> бег красивого -> красив красивыми -> красив
Видно, что формы схлопнулись к общей основе. Настоящие инструменты (стеммер Портера/Снежок, лемматизаторы pymorphy/spaCy) делают это аккуратнее, но идея та же: объединить формы, чтобы модель видела одно слово вместо десятка.
Типичный конвейер предобработки
сырой текст
→ нижний регистр
→ убрать пунктуацию/цифры (если не нужны)
→ токенизация
→ убрать стоп-слова (если задача позволяет)
→ стемминг / лемматизация
→ список нормализованных токенов
Итог
- Нормализация убирает «шум»: регистр, пунктуацию, незначащие слова, формы.
- Стоп-слова часто удаляют, но осторожно: «не» бывает важным.
- Стемминг грубо режет окончания; лемматизация даёт настоящую словарную форму.
- Хорошая предобработка делает текст «чище» и облегчает работу модели.