Aivaro
  • Оглавление
  • Вопросы
  • Практика
  • Вики
  • Материалы сообщества
  • Тесты
  • Поиск
✈Telegram @ai_varo
RUEN中文
…
Оглавление/Вопросы/#921

Как вы очищаете текст от шума (HTML-теги, спецсимволы, стоп-слова) в production RAG-пайплайне?

Краткий тезис

Очистка текста — критический этап предобработки в RAG-пайплайне, определяющий качество индексации и релевантность ответа. В production-среде требуется модульная архитектура очистки: парсинг HTML через BeautifulSoup или trafilatura, удаление спецсимволов регулярными выражениями, фильтрация стоп-слов с учётом языка (NLTK, spaCy, Stanza). Каждый шаг имеет trade-off: чрезмерное удаление (например, знаков препинания в коде C++) разрушает смысл, поэтому необходима настройка под домен.

2. Регулярные выражения для спецсимволов

После извлечения HTML остаются следы экранирования (&, <), лишние пробелы, управляющие символы (нулевой байт, табуляция), эмодзи, которые увеличивают размер индекса и зашумляют embeddings.

Типичные шаги

  1. Декодирование HTML-сущностей: html.unescape(text).
  2. Удаление управляющих символов (кроме \n, \r, \t для сохранения разметки):
    import re
    clean = re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', text)
    
  3. Удаление лишних пробелов: re.sub(r' {2,}', ' ', text).
  4. Удаление символов, не несущих смысла (специфичных для домена): например, замена множественных дефисов и тире на один пробел.
  5. Работа с эмодзи: в RAG эмодзи обычно удаляются, если только контекст (например, чаты) не требует их сохранения. Используют re.compile("[^\w\s]") с исключением букв, цифр, пробелов.

Production-рекомендации

  • Регулярные выражения компилируют один раз и применяют как sequence.
  • Для русского языка дополнительно нормализуют букву «ё» (замена на «е») и удаляют нестандартные кавычки (лапки, уголки) — оставляют только прямые или «ёлочки» в зависимости от задачи.
  • Важно: не удалять знаки препинания, нужные для структуры предложений (точка, вопросительный, восклицательный) — они влияют на chunking и смысловое деление.

3. Стоп-слова: список + учёт языка

Стоп-слова — частотные лексемы (предлоги, союзы, междометия), не несущие значимой информации для поиска. В information retrieval их удаление уменьшает размер индекса и ускоряет поиск. В современных RAG с dense retrieval роль стоп-слов снижена, поскольку трансформеры и так их учитывают, но для гибридного поиска (BM25 + embeddings) фильтрация всё ещё полезна.

Инструменты

  • NLTK: from nltk.corpus import stopwords; stopwords.words('russian') — базовый список (~150 слов).
  • spaCy: модель ru_core_news_sm включает стоп-слова как свойство токенов token.is_stop. Удобно для интеграции.
  • Stanza: более точный морфологический анализ, позволяет отсеивать стоп-слова с учётом части речи.

Учёт языка

  • Для русского языка важно не удалять местоимения в вопросительных конструкциях (что, какой, сколько) — они значимы для QA.
  • Для мультиязычных пайплайнов используют словари для каждого языка; библиотека langdetect определяет язык и выбирает соответствующий список.
  • Стоп-слова ≠ низкочастотные токены. Удаляют только общеупотребительные, оставляя термины домена (например, «контроллер» не удалять).

Пример кода

import spacy
nlp = spacy.load("ru_core_news_sm")
doc = nlp("Применение этого метода позволяет улучшить качество.")
filtered = [token.text for token in doc if not token.is_stop]

4. Trade-off: удаление значимых символов (C++)

Классический пример — исходный код на C++, где знаки препинания (скобки, точки с запятой, операторы) несут семантику. Удаление их регулярным выражением [^\w\s] разрушает синтаксис и делает текст бесполезным для индексации.

Проблема

  • В RAG-пайплайне, извлекающем код из документации, нужно сохранить символы {}, (), ;, #include, ->.
  • Решение: определять блоки кода (по маркдаун-разметке или через тег <code>) и применять к ним другую стратегию — оставлять все символы, или заменять на понятные слова (например, { → открывающая скобка).
  • Trade-off: увеличение размера чанка против сохранения смысла. Для поиска по коду лучше использовать специализированные модели (CodeBERT, GraphCodeBERT) и не удалять знаки препинания.

Методика

  1. Детекция контента с кодом (по регулярному выражению или по наличию ключевых слов #include, class, def).
  2. Если контент — код, пропустить шаг удаления спецсимволов; применить только нормализацию пробелов.
  3. Если контент — текст с примерами кода, отдельно обрабатывать блоки через markdown или BeautifulSoup (тег <pre><code>).

Практический паттерн

def is_code_block(text):
    # Простая эвристика
    return bool(re.search(r'^(#include|import |def |class |using namespace)', text, re.MULTILINE))

if is_code_block(chunk):
    # не удаляем знаки препинания
    clean = chunk.strip()
else:
    clean = remove_punctuation(chunk)

Пет-проект для закрепления

Задача: Разработать модуль очистки для корпуса из 1000 разнородных документов (HTML-статьи, Markdown, техническая документация с кодом).

Инструменты: Python, BeautifulSoup, trafilatura, re, spaCy, langdetect.

Шаги:

  1. Собрать выборку из 3 типов документов: новости (HTML), туториалы (Markdown с блоками кода), документация (HTML с тегами <code>).
  2. Реализовать функцию clean_html(html) с использованием trafilatura для извлечения текста и BeautifulSoup для fallback.
  3. Написать класс TextCleaner с методами:
    • remove_control_chars(text) — регулярное выражение.
    • normalize_whitespace(text) — удаление лишних пробелов, нормализация переносов.
    • remove_stopwords(text, lang) — на основе spaCy (сохранять части речи, удалять стоп-слова не-существительные).
    • handle_code_blocks(text) — детекция кода через эвристику, отключение удаления спецсимволов для таких блоков.
  4. Применить пайплайн ко всем документам, замерить время выполнения (цель < 50 мс на документ).
  5. Оценить качество на ручной разметке: соответствие чистого текста исходнику по 10 документам.

Ожидаемый результат: Воспроизводимый модуль очистки с документацией и тестами. Показать, что удаление стоп-слов снизило размер индекса на 15%, но не повлияло на точность ответов RAG (метрика recall@5).


Связь с другими вопросами

ВопросТема
3Предобработка текста (токенизация, лемматизация)
......

Навигация

  • Предыдущий: 920
  • Следующий: 922
  • Индекс: 00. Индекс разборов