Классификация деструктивного дискурса для автоматизированной модерации контента

Практический курс по разметке и классификации деструктивного дискурса в социальных сетях и на онлайн-платформах. Охватывает типологию вредоносного контента, критерии разметки языка вражды и токсичной речи, работу с опасным контентом, подготовку датасетов для обучения моделей машинного обучения, а также реальные кейсы автоматической фильтрации с оценкой метрик эффективности.

1. Типология деструктивного дискурса: классы, метки и границы между категориями контента

Типология деструктивного дискурса: классы, метки и границы между категориями контента

Почему два модератора, читая одну и ту же фразу «Да ты совсем спятил», могут принять диаметрально противоположные решения — один посчитает это шуткой, другой — оскорблением? Именно потому, что у деструктивного дискурса нет чёткой границы, похожей на черту на асфальте. Это скорее спектр, и задача инженера по модерации — разметить его так, чтобы алгоритм мог работать предсказуемо.

Зачем нужна типология

Любая система машинного обучения учится на метках — ярлыках, которые человек присваивает примерам из датасета. Если метки размыты, противоречивы или пересекаются, модель путается и выдаёт случайные результаты. Типология деструктивного дискурса — это карта, которая говорит модели: «Вот что значит "токсично", вот что значит "опасно", а вот — просто грубовато, но допустимо».

Без такой карты вы получите ситуацию, знакомую каждому, кто работал с датасетом Toxic Comment Classification Challenge на Kaggle: модель с точностью 97% на тесте, которая на реальных комментариях путает сарказм с угрозой, а критику — с языком вражды.

Базовые категории деструктивного дискурса

В индустрии модерации контента сложилась устойчивая иерархия из шести ключевых категорий. Каждая из них отвечает на свой вопрос о тексте.

| Категория | Вопрос, на который отвечает | Пример | |---|---|---| | Токсичная речь (toxic speech) | Нарушает ли текст нормы вежливого общения? | «Ты тупой, как пробка» | | Оскорбительная речь (abusive language) | Содержит ли текст прямые оскорбления адресата? | «Идиот, закрой рот» | | Язык вражды (hate speech) | Направлен ли текст против группы по признаку расы, пола, религии? | «Все [группа] должны убираться отсюда» | | Угрозы насилия (threats) | Содержит ли текст прямую или косвенную угрозу физического вреда? | «Я найду тебя и сломаю тебе лицо» | | Призывы к самоповреждению/суициду (self-harm content) | Поощряет ли текст причинение вреда себе или другим? | «Лучше бы ты не проснулся завтра» | | Спам и манипуляция (spam/manipulation) | Пытается ли текст обмануть, ввести в заблуждение или навязать? | «СРОЧНО! Перешли 10 людям или будет несчастье!» |

На первый взгляд категории кажутся чёткими, но на практике между ними — зона пересечения, где разметчики расходятся чаще всего.

Зона пересечения: где категории накладываются

Возьмём фразу: «Все [представители этнической группы] — воры и должны сидеть в тюрьме». Это одновременно и язык вражды (направлен против этнической группы), и токсичная речь (нарушает нормы общения), и потенциально призыв к насилию (хотя и не прямая угроза). Какую метку ставить?

Существует два подхода:

Много меток (multi-label). Один текст может получить несколько меток одновременно. Именно так устроен датасет Jigsaw: каждый комментарий может быть одновременно toxic, severe_toxic, obscene, threat, insult и identity_hate. Этот подход лучше отражает реальность, но усложняет обучение модели.

Одна метка (single-label). Текст получает только одну, самую «тяжёлую» категорию. Иерархия обычно строится по принципу потенциального вреда: угроза насилием > язык вражды > оскорбление > токсичность. Так проще обучать модели, но вы теряете нюансы.

Практика показывает, что для промышленных систем оптимален гибридный подход: модель предсказывает набор меток, а бизнес-логика определяет приоритет действий (удалить, скрыть, отправить на ручную проверку).

Принципы построения чётких границ

Чтобы разметчики расходились реже, а модель училась лучше, нужно задокументировать правила принятия решений (decision rules) для каждой категории. Вот пять принципов, которые работают на практике.

Принцип адресата. К кому направлен текст? Если к конкретному человеку — скорее всего, это оскорбление. Если к группе по защищённому признаку — язык вражды. Если ко всем без исключения — общий токсикоз.

Принцип намерения. Пытается ли автор причинить вред, унизить или запугать? Фраза «Ты ведёшь себя как идиот» в споре о погоде — оскорбление. Та же фраза в обсуждении сложного алгоритма может быть дружеским подколом. Контекст решает.

Принцип конкретности угрозы. «Я тебя убью» — прямая угроза. «Мир стал бы лучше без таких, как ты» — язык вражды без конкретной угрозы. «Кто-нибудь должен навести порядок» — серая зона, зависящая от контекста.

Принцип уязвимости аудитории. Текст в чате взрослых специалистов и тот же текст в детском форуме — разный уровень опасности. Многие платформы учитывают контекст площадки при разметке.

Принцип повторяемости. Однократная грубость — это инцидент. Систематические оскорбления в адрес одного человека — харассмент (harassment), который выделяется в отдельную категорию.

Иерархия вреда: от неприятного к опасному

Не всё деструктивное одинаково опасно. Практическая иерархия, которую используют команды модерации крупных платформ, выглядит так (от менее к более опасному):

  • Грубость (rudeness) — нарушение норм вежливости без целенаправленного вреда
  • Токсичность (toxicity) — систематическое или агрессивное нарушение норм общения
  • Оскорбление (insult/abuse) — целенаправленное унижение конкретного человека
  • Язык вражды (hate speech) — дегуманизация группы по защищённым признакам
  • Угроза (threat) — обещание причинить физический вред
  • Призыв к самоповреждению (self-harm) — потенциально смертельный контент
  • Эта иерархия определяет не только метку, но и скорость реакции: угроза требует немедленного удаления, а грубость может быть обработана с задержкой или просто снижена в рекомендациях.

    Edge cases: самые частые ловушки разметки

    Сарказм и ирония. «Ну ты гений, конечно» — похвала или оскорбление? Модели плохо понимают сарказм, потому что он строится на контексте и тоне, которые теряются в тексте. Разметчики должны помечать такие случаи отдельной меткой «сарказм/неоднозначность».

    Рекламация и цензура. «Этот продукт — полный мусор, разработчики — бездельники» — это токсичность или legitimate negative review? Критика продукта и критика людей — разные вещи, но модели часто путают их.

    Референс к защищённой группе без ненависти. «Мой сосед-мусульманин приготовил отличный плов» — упоминание религии без негативной окраски. Модели, обученные на грубом паттерне «[группа] = плохо», могут ложно срабатывать на нейтральных упоминаниях.

    Кодовый язык и эвфемизмы. Злоумышленники заменяют запрещённые слова символами, цифрами или синонимами: «гей» → «ге1», «убить» → «ликвидировать». Словарные фильтры это пропускают, а модели без специального обучения — тоже.

    Контекст площадки. Фраза «Я тебя убью» в игровом чате после проигрыша и та же фраза в личных сообщениях незнакомому человеку — совершенно разные ситуации. Разметка без учёта контекста площадки даёт шумные данные.

    Практический инструмент: карточка разметчика

    Чтобы свести разногласия к минимуму, каждая категория должна быть описана в карточке разметчика (annotation card). Вот минимальный шаблон:

  • Название категории: Язык вражды
  • Определение: Текст, который дегуманизирует, обобщает или призывает к вреду в отношении группы людей по признаку расы, этнической принадлежности, религии, пола, сексуальной ориентации, инвалидности
  • Ключевые индикаторы: Обобщения («все [группа]»), дегуманизация (сравнение с животными/болезнями), призывы к исключению/насилию
  • Не является: Критика религиозных институтов без нападок на верующих, обсуждение статистики, цитирование для осуждения
  • Примеры с метками:
  • - «Все [группа] — паразиты» → язык вражды ✓ - «Я не согласен с учением [религии]» → не язык вражды ✗ - «[Группа] должны быть изгнаны» → язык вражды ✓
  • Сложные случаи: Сатира на расизм — помечать как «сатира + потенциальный язык вражды» и отправлять на вторичную проверку
  • Такие карточки сокращают межразметочное расхождение (Cohen's Kappa) с 0.5–0.6 до 0.75–0.85, что является приемлемым порогом для обучения моделей.

    От типологии к данным

    Типология — это фундамент. Следующий шаг — применить её к реальным текстам: написать инструкции разметчикам, провести пилотную разметку, измерить согласованность и итеративно уточнить границы категорий. Именно этому посвящена следующая статья, где мы разберём критерии разметки языка вражды и токсичной речи на практических примерах.

    2. Язык вражды и токсичная речь: критерии разметки и практические примеры аннотирования

    Язык вражды и токсичная речь: критерии разметки и практические примеры аннотирования

    Когда команда модерации получает 50 000 комментариев в день, а бюджет разметки ограничен, каждое решение разметчика должно быть воспроизводимым. Если один аннотатор считает фразу «Они все одинаковые» языком вражды, а другой — нет, обученная модель будет предсказывать случайный шум. Именно поэтому критерии разметки — не бюрократия, а критически важный компонент пайплайна.

    Разница между токсичностью и языком вражды

    На первый взгляд, токсичная речь и язык вражды (hate speech) — одно и то же. Но для системы модерации это принципиально разные категории, потому что они требуют разных действий.

    Токсичная речь — это нарушение норм конструктивного общения. Она может быть направлена на кого угодно, включая неодушевлённые объекты. Ключевой признак — направленность на разрушение диалога, а не на причинение вреда конкретной группе.

    > «Эта статья — полный бред, автор вообще не разбирается в теме»

    Это токсично, но не язык вражды. Нет атаки на группу по защищённому признаку.

    Язык вражды — это атака на людей по признаку, который они не могут или не должны менять: раса, этническая принадлежность, религия, пол, сексуальная ориентация, инвалидность, национальность. Ключевой признак — обобщение и дегуманизация группы.

    > «Все [представители этнической группы] — преступники и должны быть высланы»

    Это и токсично, и является языком вражды.

    Практическое правило: весь язык вражды токсичен, но не вся токсичность — язык вражды. Это отношение подмножества, и путаница между ними — главный источник ошибок в промышленных системах.

    Критерии разметки токсичной речи

    Для токсичности существует несколько подходов к определению порога. Один из самых практических — шкала, предложенная в исследовательских проектах и адаптированная для промышленного использования.

    Уровень 0: Нетоксичный. Нейтральный или позитивный текст. Может содержать критику, но без перехода на личности.

    > «Я не согласен с этим подходом, потому что он игнорирует побочные эффекты»

    Уровень 1: Слабо токсичный. Лёгкая грубость, сарказм, пассивная агрессия. Не требует немедленного вмешательства.

    > «Ну конечно, ещё один "эксперт" с дивана расскажет, как надо делать»

    Уровень 2: Умеренно токсичный. Прямые оскорбления, переход на личности, намеренное унижение.

    > «Ты вообще думать умеешь? Такую чушь написал»

    Уровень 3: Сильно токсичный. Агрессивные оскорбления с использованием нецензурной лексики, дегуманизация.

    > «Заткнись, дебил, тебе слово не давали»

    Для обучения модели обычно бинаризуют эту шкалу: уровни 0–1 → «не токсичный», уровни 2–3 → «токсичный». Но для более точной модерации можно обучать модель на всех четырёх уровнях.

    Критерии разметки языка вражды

    Язык вражды сложнее, потому что он требует одновременной проверки нескольких условий. Вот пошаговый алгоритм, который используют разметчики.

    Шаг 1: Определяется ли в тексте целевая группа? Если нет — это не язык вражды (может быть токсичностью). Целевая группа определяется по защищённым признакам: раса, этническая принадлежность, национальность, религия, пол, гендерная идентичность, сексуальная ориентация, инвалидность, возраст.

    Шаг 2: Содержит ли текст негативное обобщение о группе? Универсальные кванторы — маркер: «все», «каждый», «такие как они», «эти люди». Сравнение с животными, болезнями, нечистью — сильный индикатор.

    Шаг 3: Направлен ли текст на дегуманизацию, исключение или вред? Призывы к насилию, изгнанию, лишению прав — очевидные случаи. Но и «они должны знать своё место» — тоже, хотя прямого призыва к насилию нет.

    Шаг 4: Есть ли контекст, который меняет смысл? Цитирование для осуждения, сатира, обсуждение статистики, исторический контекст — всё это может нейтрализовать формулировку.

    Рассмотрим на примерах:

    | Текст | Группа | Обобщение | Дегуманизация | Контекст | Метка | |---|---|---|---|---|---| | «Все [группа] — воры» | ✓ | ✓ | ✓ | — | Язык вражды | | «Статистика показывает рост преступности среди [группа]» | ✓ | ✗ | ✗ | Статистика | Не язык вражды | | «Я ненавижу [религиозное учение]» | ✗ (институт) | ✗ | ✗ | Критика идеологии | Не язык вражды | | «Я ненавижу всех [верующих]» | ✓ | ✓ | ✓ | — | Язык вражды | | «"Все [группа] — воры" — сказал политик X, и это возмутительно» | ✓ | ✓ | ✓ | Цитата для осуждения | Не язык вражды |

    Практическое аннотирование: workflow разметчика

    Вот как выглядит реальный процесс разметки в проекте, где данные готовятся для обучения классификатора.

    Этап 1: Пилотная разметка. 2–3 разметчика независимо размечают 500 примеров по инструкции. Вычисляется межразметочная согласованность — Cohen's Kappa для двух разметчиков или Fleiss' Kappa для трёх и более. Если Kappa ниже 0.6, инструкция дорабатывается.

    Этап 2: Разбор расхождений. Все случаи, где разметчики разошлись, обсуждаются совместно. Формулируются дополнительные правила для edge cases. Обновлённая инструкция — это живой документ.

    Этап 3: Основная разметка. Каждый текст размечается одним разметчиком. 10–15% текстов размечаются двумя для контроля качества. Если согласованность на контроле падает ниже 0.7, процесс останавливается для переобучения разметчиков.

    Этап 4: Валидация. Специалист (senior annotator) проверяет случайную выборку 5–10% размеченных данных. Ошибки систематического характера (например, разметчик путает критику религии с языком вражды) исправляются пакетно.

    Инструменты разметки

    Для аннотирования текстов используются специализированные платформы. Вот наиболее распространённые.

    Label Studio — open-source инструмент с гибкой настройкой интерфейса разметки. Позволяет настраивать multi-label классификацию, учитывать контекст (предыдущие сообщения в треде), задавать инструкции прямо в интерфейсе.

    Prodigy — инструмент от создателей spaCy, оптимизированный для быстрой разметки с использованием active learning. Модель предсказывает метку, разметчик подтверждает или исправляет — это ускоряет процесс в 3–5 раз.

    Amazon SageMaker Ground Truth — облачный сервис с возможностью привлечения внешних разметчиков через Amazon Mechanical Turk.

    Для небольших проектов подойдёт даже Google Sheets с колонками: text, toxic, hate_speech, insult, threat, self_harm, annotator_id, comment. Главное — не инструмент, а качество инструкции и контроль согласованности.

    Количественные пороги для принятия решений

    Разметка — это не только «да/нет». Многие системы используют непрерывные скоры — числа от 0 до 1, показывающие степень токсичности. Пороговые значения зависят от бизнес-требований:

    | Скор токсичности | Действие | Типичная платформа | |---|---|---| | | Пропустить | Любой форум | | – | Снизить в рекомендациях | Социальная сеть | | – | Отправить на ручную проверку | Маркетплейс | | | Автоматически скрыть/удалить | Игровой чат |

    Конкретные пороги настраиваются под каждую платформу. Маркетплейс Россельхозбанка «Своё Фермерство», например, использовал трёхуровневую систему: тексты с высокой вероятностью токсичности блокировались автоматически, средние — отправлялись на ручную модерацию, низкие — публиковались. Это позволило сократить нагрузку на модераторов на 60% при сохранении качества фильтрации.

    От разметки к обучению

    Когда датасет размечен и проверен, следующий вопрос — как подготовить его для модели. Несбалансированные классы, пропущенные метки, перекос в тематиках — всё это проблемы, которые решаются на этапе подготовки датасета. Этому посвящена четвёртая статья курса. Но сначала разберём самую ответственную категорию — контент, связанный с угрозами жизни.

    3. Опасный контент: выявление суицидальных призывов, призывов к самоповреждению и угроз насилия

    Опасный контент: выявление суицидальных призывов, призывов к самоповреждению и угроз насилия

    В 2017 году британский подросток Молли Рассел покончила с собой после того, как алгоритмы Instagram и Pinterest годами подавали ей контент, романтизирующий депрессию и самоповреждение. Платформы не увидели угрозу — потому что их модели были обучены на явных призывах, а не на тонких косвенных сигналах. Именно поэтому категория опасного контента требует отдельного, максимально внимательного подхода к разметке и классификации.

    Почему опасный контент — это особая категория

    В отличие от токсичности или языка вражды, где последствия ошибки — неприятный пользовательский опыт, ошибка в классификации опасного контента может стоить жизни. Это накладывает два принципиальных отличия на подход к модерации.

    Принцип recall over precision. Для обычной токсичности мы можем допустить ложные срабатывания (удалить нормальный комментарий). Для опасного контента критичнее пропустить реальную угрозу (ложноотрицательное срабатывание), чем случайно скрыть безобидный текст (ложноположительное). Порог классификации снижается: если модель не уверена на 99%, а лишь на 60%, контент всё равно отправляется на проверку.

    Принцип немедленной эскалации. Токсичный комментарий может ждать обработки часами. Угроза насилия или призыв к суициду требуют реакции в минуты. Система должна не просто классифицировать, а триггерить оповещение живого модератора или службы поддержки.

    Три подкатегории опасного контента

    Опасный контент делится на три принципиально разных подкатегории, каждая со своими лингвистическими маркерами и подходами к разметке.

    Призывы к суициду и романтизация самоповреждения

    Эта подкатегория включает не только прямые высказывания вроде «Я хочу умереть», но и целый спектр косвенных сигналов.

    Прямые призывы — наиболее очевидные случаи: «Завтра я покончу с собой», «Планирую прыгнуть с моста». Модели хорошо ловят такие формулировки, если видели их в обучающих данных.

    Косвенные сигналы — гораздо сложнее. Сюда входят:

  • Романтизация смерти: «Было бы красиво уснуть и не проснуться»
  • Прощальные сообщения: «Спасибо всем, вы были лучшими, мне пора»
  • Раздача ценных вещей: «Раздариваю все свои книги, они мне больше не понадобятся»
  • Поиск способов: «Какие таблетки самые сильные?» в контексте разговора о проблемах
  • Идеализация чужого суицида: «Она поступила правильно, наконец-то нашла покой»
  • Разметка суицидального контента требует отдельной инструкции. Вот ключевые правила:

    | Метка | Критерий | Пример | |---|---|---| | Прямой призыв к суициду | Автор прямо говорит о намерении покончить с собой | «Сегодня последний день, я не выдерживаю» | | Косвенный сигнал | Есть индикаторы, но нет прямого заявления | «Всем было бы лучше без меня» | | Романтизация | Автор восхваляет или нормализует самоповреждение/суицид | «Рубцы — это красиво, это показывает боль» | | Просьба о помощи | Автор описывает мысли о суициде, но просит поддержки | «У меня мысли о смерти, помогите, что делать» | | Информационный | Обсуждение темы суицида в образовательном/новостном контексте | «Исследование показало рост суицидов среди подростков» |

    Последняя категория — самая частая ловушка для моделей. Фраза «Исследование показало рост суицидов» содержит слово «суицид», но не является опасным контентом. Модели, обученные на bag-of-words, будут ложно срабатывать на таких текстах. Именно поэтому для этой категории критически важен контекстуальный анализ — то, что умеют трансформерные модели вроде BERT, но плохо делают линейные классификаторы.

    Угрозы насилия

    Угрозы делятся на конкретные и абстрактные. Конкретная угроза содержит указание на жертву, способ и/или время: «Я приду к тебе домой и сломаю тебе челюсть». Абстрактная угроза не привязана к конкретному человеку или моменту: «Кто-нибудь должен дать этим людям по морде».

    Для разметки угроз используется шкала конкретности:

  • Абстрактная угроза без адресата — «Мир стал бы лучше без таких людей»
  • Абстрактная угроза с адресатом — «Тебе бы дали по морде»
  • Конкретная угроза без деталей — «Я тебя найду»
  • Конкретная угроза с деталями — «Завтра в 15:00 приду в твой офис»
  • Чем выше конкретность, тем выше приоритет обработки. Угрозы уровня 3–4 требуют немедленной эскалации, включая передачу данных в правоохранительные органы (в юрисдикциях, где это предусмотрено).

    Важный edge case: игровой контекст. «Я тебя убью» в чате онлайн-игры после проигранного раунда — стандартная фраза, не несущая реальной угрозы. Разметка должна учитывать контекст площадки, а модель — получать метаданные об источнике текста.

    Призывы к насилию в отношении других

    Отличие от угроз: призыв не направлен лично, а адресован аудитории. «Надо бы всех [группа] перебить» — это не угроза конкретному человеку, а призыв к насилию против группы. Такие тексты часто пересекаются с языком вражды и требуют двойной метки.

    Практический пайплайн обработки опасного контента

    Вот как выглядит архитектура системы, которая обрабатывает опасный контент в реальном времени.

    Слой 1: Быстрый фильтр. Регулярные выражения и словари ловят очевидные паттерны: «я хочу умереть», «покончу с собой», «убью тебя». Этот слой работает за миллисекунды и покрывает 40–50% случаев.

    Слой 2: Контекстуальная модель. Трансформерная модель (BERT, RoBERTa или их мультиязычные аналоги) анализирует текст с учётом контекста. Она ловит косвенные сигналы, сарказм и нестандартные формулировки. Скорость — 50–200 мс на текст.

    Слой 3: Человеческая проверка. Все тексты, которые модель классифицировала с уверенностью ниже порога (обычно 0.7 для опасного контента), а также все тексты с максимальным скором, попадают в очередь модератора. Время реакции — до 15 минут.

    Слой 4: Эскалация. Тексты с конкретными угрозами или прямыми призывами к суициду триггерят оповещение ответственного сотрудника и, при необходимости, передаются в службы экстренной помощи.

    Особенности разметки: что отличает опасный контент от остальных

    Многоязычность. Суицидальные призывы на редких языках или диалектах — слепая зона большинства моделей. Датасеты для обучения катастрофически несбалансированы: 90%+ данных на английском, остальные языки представлены фрагментарно.

    Эвфемизмы и кодовый язык. Пользователи, которые не хотят быть заблокированными, используют замены: «unalive» вместо «kill», «sewerslide» вместо «suicide», «SH» вместо «self-harm». Словари нужно обновлять еженедельно, а модели — дообучать на новых паттернах.

    Контекстные инверсии. «Я убил эту задачу на экзамене» — позитивное высказывание, содержащее слово «убил». «Помогите, я не могу больше» — потенциальный крик о помощи без единого «опасного» слова. Модели без глубокого контекстуального понимания будут систематически ошибаться в обоих направлениях.

    Эмоциональная нагрузка на разметчиков. Разметка суицидального контента — психологически тяжёлая работа. Практические рекомендации: ограничивать сессии разметки до 2 часов, обеспечивать доступ к психологу, чередовать с разметкой нейтрального контента. Это не «мягкие» меры — это требования, от которых зависит качество данных.

    Метрики, специфичные для опасного контента

    Для этой категории стандартные метрики (accuracy, F1) недостаточны. Нужны специализированные показатели.

    Recall на опасном классе — главная метрика. Сколько реальных угроз нашла модель? Если recall ниже 0.95, система неприемлема для продакшена.

    Время до реакции — сколько времени прошло от публикации до удаления/эскалации. Для прямых угроз целевое время — менее 5 минут.

    False negative rate по severity — процент пропущенных угроз высокой конкретности. Даже 1% пропусков на уровне «конкретная угроза с деталями» — критическая проблема.

    Переходя к следующей теме: все эти данные, размеченные по категориям, нужно ещё правильно подготовить для обучения модели. Несбалансированные классы, мульти-лейбл разметка, шумные метки — вот что ждёт вас в следующей статье о подготовке датасетов.

    4. Подготовка и балансировка датасетов для обучения классификаторов деструктивного контента

    Подготовка и балансировка датасетов для обучения классификаторов деструктивного контента

    Представьте, что вы собрали 100 000 комментариев и разметили их. 95% — нормальные, 3% — токсичные, 1.5% — оскорбительные и 0.5% — язык вражды. Если вы подадите эти данные в модель как есть, она научится просто предсказывать «нормальный» для каждого текста — и получит accuracy 95%, которая ничего не значит. Это проблема дисбаланса классов, и она — главный технический вызов при создании датасетов для модерации контента.

    Сбор данных: откуда брать тексты

    Качество модели начинается с качества данных. Вот основные источники текстов для датасетов модерации.

    Открытые датасеты. Jigsaw Toxic Comments (английский, 160K комментариев с Wikipedia), HateXplain (английский, 20K с объяснениями разметчиков), OffComBR (португальский), и русскоязычный набор с Kaggle для токсичных комментариев. Эти датасеты дают старт, но почти всегда требуют адаптации под конкретную платформу.

    Собственные данные. Комментарии, посты и сообщения с вашей платформы — самый ценный источник, потому что они отражают реальный язык вашей аудитории. Россельхозбанк, например, собрал объявления с сельскохозяйственных порталов, потому что стандартные датасеты не учитывали специфику агросферы, где фраза «свиное рыло» — не оскорбление, а товар.

    Синтетические данные. Генерация токсичных текстов с помощью языковых моделей. Исследования показывают, что LLM способны генерировать правдоподобные примеры токсичного контента, если им отключить внутренний цензор. Однако синтетические данные не заменяют реальные, а лишь дополняют их для балансировки.

    Краудсорсинг. Привлечение внешних разметчиков через платформы вроде Toloka, Amazon Mechanical Turk или Label Studio Cloud. Плюс — масштаб. Минус — качество нужно контролировать через gold-standard примеры.

    Проблема дисбаланса: цифры и последствия

    В реальных данных деструктивный контент составляет 1–5% от общего объёма. Это создаёт три проблемы.

    Модель игнорирует миноритарный класс. Если 98% текстов — нормальные, модель может достичь 98% accuracy, просто предсказывая «нормальный» для всего. При этом recall на токсичных текстах будет 0%.

    Метрики вводят в заблуждение. Accuracy становится бесполезной. Даже precision и recall нужно интерпретировать с учётом дисбаланса. Метрика F1-score (гармоническое среднее precision и recall) и ROC-AUC — минимальный набор для оценки.

    Модель не видит разнообразия миноритарного класса. Если у вас 500 примеров языка вражды, модель не увидит всех нюансов: сарказм, эвфемизмы, культурные контексты.

    Стратегии балансировки

    Есть четыре основных подхода, и на практике их комбинируют.

    Стратифицированная выборка (undersampling)

    Уменьшаем количество примеров мажоритарного класса так, чтобы соотношение стало ближе к 1:1 или 1:3. Случайный undersampling прост, но теряет данные. Tomek Links и Edited Nearest Neighbours — более умные методы, которые удаляют только пограничные примеры мажоритарного класса, не несущие полезной информации.

    Плюсы: быстрое обучение, нет искажения данных. Минусы: потеря информации, плохо работает при очень сильном дисбалансе (1:100 и хуже).

    Oversampling миноритарного класса

    Увеличиваем количество примеров редких категорий. SMOTE (Synthetic Minority Over-sampling Technique) создаёт синтетические примеры, интерполируя между существующими. ADASYN адаптивно генерирует больше примеров в сложных областях пространства признаков.

    Для текстовых данных классический SMOTE не подходит (нельзя интерполировать между векторами слов). Вместо него используют:

  • Back-translation: перевод текста на другой язык и обратно с получением paraphrase
  • Синонимическая замена: замена слов синонимами через WordNet или языковую модель
  • Генерация через LLM: «Перефразируй этот токсичный комментарий, сохранив токсичность, но изменив формулировку»
  • Взвешивание классов (class weights)

    Вместо изменения данных меняем функцию потерь модели. Классу с меньшим количеством примеров присваивается больший вес. В scikit-learn это параметр class_weight='balanced', в PyTorch — аргумент weight в CrossEntropyLoss.

    Формула для вычисления веса класса :

    где — общее количество примеров, — количество классов, — количество примеров класса . Так для класса с 500 примерами из 100 000 вес будет в 200 раз выше, чем для мажоритарного класса.

    Изменение порога классификации

    После обучения модели можно сдвинуть порог принятия решения. Вместо стандартного 0.5 используем 0.3 для опасного контента (ловим больше) и 0.7 для спама (ловим точнее). Порог подбирается по precision-recall curve под конкретные бизнес-требования.

    Multi-label разметка: особенности подготовки

    Многие тексты относятся сразу к нескольким категориям. Фраза «Все [группа] — идиоты, которые заслуживают смерти» — это одновременно язык вражды, оскорбление и косвенная угроза. Multi-label классификация требует специальной подготовки.

    Формат данных. Вместо одной колонки label используем бинарные колонки для каждой категории: toxic, hate_speech, insult, threat, self_harm. Каждая принимает значение 0 или 1.

    Модели. Два подхода: (1) отдельная бинарная модель для каждой категории (One-vs-Rest), (2) одна модель с несколькими выходами и сигмоидой на каждом (не softmax, потому что классы не взаимоисключающие).

    Метрики. Hamming Loss — доля неверных меток. Subset Accuracy — доля текстов, где все метки угаданы верно. Micro/Macro F1 — усреднённые F1 по всем категориям.

    Очистка данных: борьба с шумом

    Даже после разметки в данных остаётся шум: ошибки разметчиков, дубликаты, мусорные тексты.

    Дубликаты. Идентичные или почти идентичные тексты создают переобучение. Используем cosine similarity на эмбеддингах с порогом 0.95 для удаления дубликатов.

    Противоречивые метки. Если один и тот же текст разными разметчиками помечен по-разному, есть три варианта: (1) удалить, (2) оставить мажоритарную метку, (3) пометить как «неопределённый» и исключить из обучения.

    Мусорные тексты. Пустые строки, тексты из одного символа, бессмысленный набор букв — всё это удаляется на этапе предобработки.

    Несбалансированные разметчики. Если один разметчик ставит «токсичный» в 30% случаев, а другой — в 5%, их метки несопоставимы. Нужно нормализовать или переразметить.

    Train/Validation/Test split: как правильно делить

    Для датасетов модерации стандартное случайное разделение 70/15/15 может быть ошибкой.

    Стратифицированное разделение — сохраняем пропорции классов в каждом сплите. Если в полном датасете 2% языка вражды, то и в train, и в validation, и в test должно быть примерно 2%.

    Временное разделение — если данные собраны за длительный период, тестовая выборка должна содержать только самые свежие данные. Язык токсичности эволюционирует: то, что было токсичным в 2020 году, может не считаться таковым в 2025, и наоборот.

    Разделение по пользователям — один пользователь не должен встречаться и в train, и в test. Иначе модель может выучить стиль конкретного пользователя, а не общие паттерны токсичности.

    Пайплайн подготовки данных

    Вот пошаговый workflow, который можно адаптировать под любой проект.

  • Собрать данные из всех источников
  • Провести первичную очистку (удалить дубликаты, мусор, пустые строки)
  • Провести пилотную разметку на 500 примерах, измерить Kappa
  • Доработать инструкцию, провести основную разметку
  • Проверить качество разметки (gold-standard контроль)
  • Провести EDA: распределение классов, корреляции, edge cases
  • Применить стратегию балансировки (undersampling + oversampling + class weights)
  • Сделать стратифицированный train/val/test split
  • Задокументировать все решения и параметры
  • Когда датасет готов, наступает время обучения модели и оценки её качества. Именно этому — практическим кейсам, выбору архитектуры и метрикам — посвящена финальная статья курса.

    5. Практические кейсы модерации: модели, метрики эффективности и оценка качества фильтрации

    Практические кейсы модерации: модели, метрики эффективности и оценка качества фильтрации

    Почему одна команда запускает систему модерации за три недели, а другая полгода бьётся с accuracy 92%, которая на проде превращается в 70%? Разница не в размере датасета и не в количестве GPU. Разница в выборе архитектуры под задачу, правильных метриках и понимании того, что accuracy — это последнее, на что нужно смотреть.

    Выбор архитектуры: от линейных моделей к трансформерам

    Не каждая задача модерации требует BERT. Выбор модели зависит от трёх факторов: объём данных, требуемая скорость и допустимая ошибка.

    Базовый уровень: логистическая регрессия + TF-IDF

    Логистическая регрессия на TF-IDF признаках — это baseline, с которого начинается любой проект. Как показал опыт команды Россельхозбанка, такая модель даёт ROC-AUC 0.92 на задаче классификации токсичных текстов на русском языке. Этого достаточно для первой версии системы, особенно если данных мало ( размеченных примеров).

    Плюсы: обучается за секунды, работает за миллисекунды, легко интерпретируется (можно посмотреть, какие слова модель считает токсичными). Минусы: не понимает контекст, путает сарказм, плохо работает с замаскированными оскорблениями.

    Средний уровень: наивный классификатор + логистическая регрессия

    Комбинация словарного фильтра (отсечение текстов с матом) и логистической регрессии для остальных. Именно этот подход использовался в проекте «Своё Фермерство»: наивный классификатор ловил очевидные случаи, а логистическая регрессия обрабатывала остальные. Итоговый ROC-AUC — 0.939, что на 1.8 пункта выше, чем у单独 логистической регрессии.

    Это работает, потому что словарный фильтр — идеальный классификатор для своей узкой задачи: если слово из списка есть в тексте, токсичность равна 1 с вероятностью 99%.

    Продвинутый уровень: BERT и его варианты

    Трансформерные модели понимают контекст и ловят то, что недоступно линейным моделям. В упомянутом проекте BERT поднял ROC-AUC до 0.960, а в связке с наивным классификатором — до 0.963. Прирост кажется небольшим, но на объёме в миллионы текстов это тысячи правильно классифицированных случаев.

    Для русского языка используются RuBERT (от DeepPavlov), multilingual BERT или XLM-RoBERTa. Для английского — RoBERTa, DeBERTa или специализированные модели вроде Perspective API от Google.

    Передовой уровень: LLM с few-shot и fine-tuning

    Большие языковые модели могут классифицировать токсичность без дообучения — достаточно дать несколько примеров в промпте. Но для промышленного использования это слишком медленно и дорого. Практический подход: использовать LLM для генерации обучающих данных и разметки, а для инференса — дообученную малую модель.

    Исследование, опубликованное на Хабре, показало, что LLM с отключённым внутренним цензором отлично справляются не только с нейтрализацией токсичности, но и с её генерацией — что подтверждает их глубокое понимание природы токсичного языка.

    Метрики: что измерять и почему accuracy не подходит

    Для задач модерации стандартная accuracy — ловушка. Если 95% текстов нетоксичны, модель, которая всегда предсказывает «нетоксичный», получит accuracy 95%. При этом она не найдёт ни одного токсичного комментария.

    Метрики для бинарной классификации

    Precision — какая доля текстов, помеченных как токсичные, действительно токсична. Высокий precision = мало ложных срабатываний = не удаляем нормальные комментарии.

    где — true positives (токсичные, правильно найденные), — false positives (нетоксичные, ошибочно помеченные).

    Recall — какую долю токсичных текстов нашла модель. Высокий recall = мало пропусков = не оставляем токсичные комментарии на платформе.

    где — false negatives (токсичные, пропущенные моделью).

    F1-score — гармоническое среднее precision и recall. Баланс между двумя метриками.

    ROC-AUC — площадь под ROC-кривой. Показывает, насколько модель разделяет классы при всех возможных порогах. Значение 0.5 = случайное угадывание, 1.0 = идеальное разделение.

    Метрики для multi-label классификации

    Hamming Loss — доля неверных предсказаний отдельных меток. Чем ниже, тем лучше.

    Subset Accuracy — доля текстов, где ВСЕ метки предсказаны верно. Самая строгая метрика.

    Micro/Macro F1 — micro усредняет по всем примерам (с учётом дисбаланса), macro — по всем классам (без учёта дисбаланса). Macro F1 важнее, если нужно хорошо классифицировать редкие категории.

    Бизнес-метрики

    Помимо ML-метрик, система модерации оценивается по бизнес-показателям.

    Время до удаления — от публикации токсичного контента до его скрытия. Целевое значение: минут для угроз, час для токсичности.

    Доля ручной модерации — какой процент контента требует проверки человеком. Чем ниже, тем дешевле система.

    Количество апелляций — сколько пользователей оспорили решение системы. Рост апелляций = рост ложных срабатываний.

    User-reported toxicity rate — сколько токсичных комментариев репортят пользователи после внедрения системы. Если система работает, этот показатель падает.

    Кейс 1: Маркетплейс «Своё Фермерство» (Россельхозбанк)

    Задача: премодерация текстовых описаний товаров на сельскохозяйственном маркетплейсе.

    Специфика: фразы, которые в обычной жизни являются оскорблениями, в сельскохозяйственном контексте могут быть нормой. «Свиное рыло» — это товар, а не оскорбление.

    Архитектура: трёхуровневая система: наивный классификатор (словарь обсценной лексики) → BERT (RuBERT от DeepPavlov) → логистическая регрессия (страховка при сбое нейросети).

    Результаты:

    | Метрика | Наивный | LR | BERT | Наивный + BERT | |---|---|---|---|---| | Accuracy | 0.854 | 0.865 | 0.901 | 0.909 | | ROC-AUC | 0.782 | 0.921 | 0.960 | 0.963 | | F1 | 0.722 | 0.800 | 0.840 | 0.855 |

    Ключевой инсайт: комбинация простого словарного фильтра и нейросети даёт прирост, потому что словарь ловит очевидные случаи, а BERT — контекстуальные. Скорость: 2800 текстов в минуту на одной GPU.

    Кейс 2: Детоксификация текстов (PAN at CLEF 2024)

    Задача: преобразование токсичных текстов в нейтральные на 9 языках.

    Подход: Llama 3 с отключённым внутренним цензором через abliteration — метод, который находит направления активации, отвечающие за отказ модели, и подавляет их.

    Результаты: система заняла первое место при автоматической оценке и первое место при ручной оценке. Для русского, испанского и немецкого языков качество модели превысило качество человеческих правок.

    Ключевой инсайт: внутренний цензор LLM мешает не только генерации токсичного контента, но и его нейтрализации — потому что модель видит токсичный текст и отказывается с ним работать. Удаление цензора решает обе проблемы.

    Кейс 3: Модерация комментариев (Jigsaw/Kaggle)

    Задача: multi-label классификация комментариев по 6 категориям: toxic, severe_toxic, obscene, threat, insult, identity_hate.

    Подход: извлечение числовых признаков (длина текста, верхний регистр, пунктуация, смайлики) и объединение с TF-IDF через DataFrameMapper. Классификатор — логистическая регрессия.

    Ключевой инсайт: даже без нейросетей, правильный feature engineering даёт результат. Признаки вроде количества восклицательных знаков и символов верхнего регистра коррелируют с токсичностью и помогают модели. Лучше всего классификатор справился с непристойными комментариями (obscene) — потому что у них есть специфичные слова, которые хорошо отделяют их от остальных.

    Оценка качества: от метрик к продакшену

    Метрики на тестовой выборке — необходимый, но недостаточный этап. Перед запуском в продакшен нужно провести ещё три проверки.

    A/B-тест на живом трафике. Запустить модель на 5–10% трафика и сравнить с текущей системой (или ручной модерацией). Сравниваем не только ML-метрики, но и бизнес-метрики: жалобы пользователей, время модерации, конверсии.

    Стресс-тест на adversarial examples. Специально подготовленные тексты, которые пытаются обмануть модель: замена букв символами («т0ксичный»), вставка пробелов («т о к с и ч н ы й»), использование эмодзи вместо слов. Если модель ломается на таких примерах, её нужно дообучить.

    Анализ ошибок. Разобрать 200–300 случайных ошибок модели (и false positives, и false negatives). Часто выясняется, что 80% ошибок приходятся на 2–3 систематических паттерна (например, сарказм или специфический сленг), и исправление этих паттернов даёт больший прирост, чем замена архитектуры.

    Мониторинг и непрерывное улучшение

    Модель, запущенная в продакшен, деградирует. Язык меняется, появляются новые формы токсичности, злоумышленники адаптируются. Система мониторинга должна отслеживать:

    Drift данных. Распределение входящих текстов меняется со временем. Если модель обучена на комментариях 2023 года, а в 2025 году появился новый сленг, accuracy будет падать. Инструменты: Population Stability Index (PSI), сравнение распределений скоров модели на скользящем окне.

    Drift метрик. Падение F1 на свежеразмеченных данных — сигнал к переобучению. Автоматический пайплайн: каждую неделю размечается 500 случайных текстов, вычисляются метрики, при падении ниже порога запускается дообучение.

    Обратная связь от пользователей. Апелляции на блокировки — ценнейший источник данных. Если пользователь оспорил блокировку и оказался прав, его текст — кандидат на включение в обучающую выборку с правильной меткой.

    Практические рекомендации: чек-лист запуска

  • Начинайте с baseline: логистическая регрессия + TF-IDF. Не тратьте месяц на BERT, если baseline даёт F1 0.85
  • Оптимизируйте под recall для опасного контента и под precision для спама — это разные задачи с разными порогами
  • Всегда оставляйте человека в петле: автоматическая модерация дополняет, а не заменяет ручную
  • Собирайте данные непрерывно: каждое решение модели (и правильное, и ошибочное) — потенциальный обучающий пример
  • Тестируйте на adversarial examples до запуска, а не после первого скандала
  • Документируйте все решения: какая модель, какие данные, какие пороги, почему именно так
  • Автоматизированная модерация — это не проект с конечной датой, а непрерывный процесс. Модель, данные, инструкции разметчиков и бизнес-требования эволюционируют вместе с языком и аудиторией платформы.