Предварительная обработка текстовых данных: ключевые этапы и методы
Текстовые данные — один из самых сложных типов данных для анализа из-за их неструктурированной природы и высокой вариативности. Чтобы превратить "сырой" текст в информацию, пригодную для машинного обучения или лингвистического анализа, требуется предварительная обработка. Этот процесс включает стандартизацию, очистку и преобразование текста, что повышает качество моделей NLP (Natural Language Processing). Рассмотрим основные этапы и методы.
# создание функции очистки текстовых данных
def clean_text(text):
# Приведение текста к нижнему регистру
text = text.lower()
# Замена всех не-словесных символов на пробел (кроме букв и знаков препинания)
text = re.sub(r'W+', ' ', text)
# Удаление URL-адресов
text = re.sub(r"httpS+", "", text)
# Создание шаблона для HTML-тегов
html = re.compile(r'<.*?>')
# Удаление HTML-тегов из текста
text = html.sub(r'', text)
# Список пунктуаций для удаления
punctuations = '@#!?+&*[]-%.:/();$=><|{}^' + "'`" + '_'
for p in punctuations:
text = text.replace(p, '') # Удаление пунктуации
# Удаление стоп-слов и приведение слов к нижнему регистру
text = [word.lower() for word in text.split() if word.lower() not in sw]
# Объединение слов обратно в текст
text = " ".join(text)
# Создание шаблона для поиска эмодзи
emoji_pattern = re.compile("["
u"U0001F600-U0001F64F" # эмоции
u"U0001F300-U0001F5FF" # символы и пиктограммы
u"U0001F680-U0001F6FF" # транспорт и карты
u"U0001F1E0-U0001F1FF" # флаги
u"U00002702-U000027B0"
u"U000024C2-U0001F251"
"]+", flags=re.UNICODE)
# Удаление эмодзи из текста
text = emoji_pattern.sub(r'', text)
return text
Функция выполняет следующие действия:
-
Приведение к нижнему регистру
-
Удаление всех спецсимволов
-
Удаление URL адресов
-
Удаление HTML-тегов
-
Удаление пунктуации
-
Очистка от стоп-слов
-
Удаление эмодзи
Приведение к нижнему регистру стандартизирует текстовые данные и позволяет воспринимать разные формы слова как одну. Спецсимволы не несут никакой смысловой нагрузки и путают алгоритмы кластеризации. При рассмотрении жалоб, нам не приносят никакой информации URL адреса и HTML-теги. Убирая пунктуацию, мы убираем лишние шумы в данных и сокращаем размер словаря. Удаление стоп-слов для обучения модели помогает уменьшить объём текста и сосредоточиться на важных и значимых словах. Эмодзи создают шумы в данных и не несут смысловой нагрузки при рассмотрение нашей проблемы.
# инициализация анализатора(лемматизатора)
morph = pymorphy3.MorphAnalyzer()
# инициализация функции лемматизации текстовых данных
def lemmatize(text: str) -> str:
# создание списка лемматизированных слов
lemmas = [morph.parse(token)[0].normal_form for token in text.split()]
# объединение слов в текст
processed_text = " ".join(lemmas)
return processed_text
Загрузка и нормализация текста
Первый шаг — приведение текста к единому формату. Это включает:
-
Удаление лишних символов: HTML-тегов, спецсимволов (например, n, t), эмодзи или URL-ссылок.
-
Нормализация кодировки (например, UTF-8) для корректного отображения символов.
-
Приведение к нижнему регистру для устранения различий между словами в разном регистре (например, "Текст" → "текст").
Пример:
Исходный текст: "ПРИвет! Посетите наш сайт: https://example.com "
После обработки: "привет посетите наш сайт ".
# Подсчитываем количество каждой
category_counts = Counter(df.cat)
# Строим гистограмму
sns.barplot(x = [i for i in range(len(set(df.cat)))], y=list(category_counts.values()))
plt.xlabel('cat')
plt.ylabel('Frequency')
plt.title('Histogram with cat')
plt.show()
2. Токенизация
Разделение текста на отдельные элементы — токены (слова, предложения). Для этого используются:
-
Словесная токенизация: разбивка по пробелам и знакам препинания.
-
Сентенциальная токенизация: разделение на предложения с учётом контекста (например, с помощью библиотек NLTK или SpaCy).
Пример:
Текст: "Машинное обучение — это интересно. А вы согласны?"
Токены: ["Машинное", "обучение", "—", "это", "интересно", ".", "А", "вы", "согласны", "?"].
Для выделения значимых частей речи был выбран анализатор частей речи из библиотеки pymorphy3, благодаря его скорости работы и разнообразию токенов для работы с русским языком. В качестве значимых частей речи были выбраны:
# инициализация анализатора частей речи
morph = pymorphy3.MorphAnalyzer()
# инициализация функции фильтрации слов по частям речи
def filter_words(text):
# разбиение текста на слова
words = text.split()
# инициализация итогового списка отфильтрованных
filtered_words = []
# фильтрация слов по частям речи
for word in words:
parsed_word = morph.parse(word)[0]
if parsed_word.tag.POS in {'NOUN', 'ADJF', 'ADJS', 'INFN', 'VERB'}: # если это существительное, прилагательное или глагол
filtered_words.append(word)
# объединение слов в текст
processed_text = " ".join(filtered_words)
return processed_text
Фильтрация текста по значимым частям речи необходима для удаления мусора, и дальнейщего ускорения работы и повышения точности алгоритмов машинного обучения. Для реализации фильтрации слов были использованы данные токены:
-
NOUN(имя существительное)
-
ADJF(имя прилагательное (полное))
-
ADJS(имя прилагательное (краткое))
-
VERB(глагол (личная форма))
-
INFN(глагол (инфинитив))
Удаление стоп-слов
Стоп-слова — частые, но малозначимые слова (предлоги, союзы, местоимения). Их удаление сокращает шум и размер данных. Списки стоп-слов встроены в библиотеки (NLTK, SpaCy) или настраиваются вручную.
Пример:
До: ["и", "машинное", "обучение", "на", "практике"]
После: ["машинное", "обучение", "практике"].
Лемматизация и стемминг
-
Стемминг — грубое отсечение окончаний (например, Porter, Snowball stemmer).
-
Лемматизация — приведение слова к словарной форме (лемме) с учётом контекста и части речи.
Пример:
Слово: "бегущий"
Стемминг: "бег"
Лемматизация: "бежать".
# инициализация функции токенизации текстовых данных
def tokenize(text):
# применение метода word_tokenize из библиотеки nltk
tokenized_text = word_tokenize(text)
return tokenized_text
Токенизация необходима для разбиения на токены, которые вдальнейшем просто и удобно преобразовать в числовые значения. Также она приводит текстовые данные к формату, эффективному при обработке различными алгоритмами.
Обработка пунктуации и чисел
-
Удаление знаков препинания, если они не несут смысловой нагрузки (например, в классификации текстов).
-
Замена чисел на токены (например, <NUM>) или их удаление.
Пример:
Текст: "Цена: 2000 руб."
После обработки: "цена num руб".
Для поиска ключевых слов был выбран алгоритм выбора самого часто встречающегося слова. Поскольку скорость работы данного алгоритма оптимальна, также данный алгоритм помогает находит слово которое максимально отражает контекст, так как если слово упоминается несколько раз
# инициализация функции поиска ключевого слова
def extract_keywords(tokens, top_n=5):
keywords = [word for word, _ in Counter(tokens).most_common(top_n)]
# выбор самых часто встречающихся слов в зависимости от количества слов
if len(keywords) == 1: keyword = [keywords[0]]
else: keyword = keywords[:2]
return keyword
Выбор ключевого слова необходим для лучшего понимания моделью главной мысли текста. Данное действие повысит точность разбиения на кластеры и поможет модели меньше путаться при разбиении.
Исправление опечаток
Автокоррекция орфографических ошибок с помощью алгоритмов (например, библиотека pyspellchecker) или нейросетевых моделей.
Пример:
Ошибочное: "програмирование" → Исправленное: "программирование".
Для поиска и добавления биграмм в качестве признака воспользуемся встроеным в библиотеку nltk методом bigrams, это метод позволяет автоматизированно находить биграммы по каждому предложению. Данный способ обнаружения является быстрым и эффективным.
# cоздание списка биграмм
bigrams_arr = np.array(df['text'].progress_apply(lambda x: list(nltk.bigrams(x))))
bigrams_arr
Работа с редкими словами и N-граммами
-
Фильтрация редких терминов, которые встречаются реже заданного порога.
-
Извлечение N-грамм (последовательностей из N слов) для учета контекста (например, "искусственный интеллект").
# инициализация функции преобразования n-грамм
def process_ngrams(ngrams_list):
return ['_'.join(ngram) for ngram in ngrams_list]
Векторизация текста
Преобразование текста в числовой формат:
-
Bag of Words (BoW) — частотное представление слов.
-
TF-IDF — учёт важности слов в документе и корпусе.
-
Word Embeddings (Word2Vec, GloVe) — векторные представления с учётом семантики.
-
BERT и трансформеры — контекстные эмбеддинги.
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(df['text'].progress_apply(lambda x: " ".join(x)))
X
Заключение
Предварительная обработка текста — критически важный этап, от которого зависят результаты NLP-моделей. Выбор методов зависит от задачи: например, для анализа тональности стоп-слова могут сохраняться, а для классификации документов — удаляться. Современные инструменты (NLTK, SpaCy, Hugging Face) автоматизируют большинство шагов, но понимание логики каждого этапа позволяет гибко настраивать процесс под конкретные требования.
Автор: agushin