Как стать автором
Обновить

Построение автоматической системы модерации сообщений

Время на прочтение9 мин
Количество просмотров8K
image
Автоматические системы модерации внедряются в веб-сервисы и приложения, где необходимо обрабатывать большое количество сообщений пользователей. Такие системы позволяют сократить издержки на ручную модерацию, ускорить её и обрабатывать все сообщения пользователей в real-time. В статье поговорим про построение автоматической системы модерации для обработки английского языка с использованием алгоритмов машинного обучения. Обсудим весь пайплайн работы от исследовательских задач и выбора ML алгоритмов до выкатки в продакшен. Посмотрим, где искать готовые датасеты и как собрать данные для задачи самостоятельно.


Подготовлено совместно с Ирой Степанюк (id_step), Data Scientist в Poteha Labs

Описание задачи


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

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

Токсичные Нормальные
Your are a damn fag*ot this book is so dummy
ur child is so ugly (1) Winners win, losers make excuses
White people are owners of black (2) black like my soul (2)

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

Данные


Открытые данные


Одним из самых известных датасетов по задаче модерации является датасет с соревнования на Kaggle Toxic Comment Classification Challenge. Часть разметки в датасете некорректна: например, сообщения с нецензурными словами могут быть отмечены как нормальные. Из-за этого нельзя просто взять Kernel соревнования и получить хорошо работающий алгоритм классификации. Нужно больше работать с данными, смотреть, каких примеров недостаточно, и добавлять дополнительные данные с такими примерами.

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

Данные, собранные вручную


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

image

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

Аугментация данных


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

  • генерируют опечатки: you are stupid asswhole, fack you,
  • заменяют буквенные символы на цифры, похожие по описанию: n1gga, b0ll0cks,
  • вставляют дополнительные пробелы: i d i o t,
  • удаляют пробелы между словами: dieyoustupid.


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

Описание подзадач


Перед нами стояли подзадачи по анализу сообщения в двух разных режимах:

  • онлайн режим — real-time анализ сообщений, с максимальной скоростью ответа;
  • офлайн режим — анализ логов сообщений и выделение токсичных диалогов.

В онлайн режиме мы обрабатываем каждое сообщение пользователей и прогоняем его через модель. Если сообщения токсичное, то скрываем его в интерфейсе чата, а если нормальное, то выводим. В таком режиме все сообщения должны обрабатываться очень быстро: модель должна выдавать ответ настолько быстро, чтобы не нарушать структуру диалога между пользователями.
В офлайн режиме ограничений по времени работы нет, и поэтому хотелось реализовать модель с максимальным качеством.

Онлайн режим. Поиск слов по словарю


Вне зависимости от того, какая модель будет выбрана дальше, мы должны находить и фильтровать сообщения с нецензурными словами. Для решения этой подзадачи проще всего составить словарь недопустимых слов и выражений, которые точно нельзя пропускать, и делать поиск таких слов в каждом сообщении. Поиск должен происходить быстро, поэтому наивный алгоритм поиска подстрок за такое то время не подходит. Подходящим алгоритмом для поиска набора слов в строке является алгоритм Ахо-Корасик. За счет такого подхода удается быстро определять некоторые токсичные примеры и блокировать сообщения еще до их передачи в основной алгоритм. Использование ML алгоритма позволит «понимать смысл» сообщений и улучшить качество классификации.

Онлайн режим. Базовая модель машинного обучения


Для базовой модели решили использовать стандартный подход для классификации текстов: TF-IDF + классический алгоритм классификации. Опять же из соображений скорости и производительности.

TF-IDF — это статистическая мера, которая позволяет определить наиболее важные слова для текста в корпусе с помощью двух параметров: частот слов в каждом документе и количества документов, содержащих определенное слово (более подробно здесь). Рассчитав для каждого слова в сообщении TF-IDF, получаем векторное представление этого сообщения.
TF-IDF можно рассчитывать для слов в тексте, а также для n-грам слов и символов. Такое расширение будет работать лучше, так как сможет обрабатывать часто встречающиеся словосочетания и слова, которых не было в обучающей выборке (out-of-vocabulary).

from sklearn.feature_extraction.text import TfidfVectorizer
from scipy import sparse
vect_word = TfidfVectorizer(max_features=10000, lowercase=True, 
  analyzer='word', min_df=8, stop_words=stop_words, ngram_range=(1,3))
vect_char = TfidfVectorizer(max_features=30000, lowercase=True,
   analyzer='char', min_df=8, ngram_range=(3,6))

x_vec_word = vect_word.fit_transform(x_train)
x_vec_char = vect_char.fit_transform(x_train)
x_vec = sparse.hstack([x_vec_word, x_vec_char])
Пример использования TF-IDF на n-грамах слов и символов

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

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

Полученный с использованием TF-IDF и логистической регрессии алгоритм быстро работает и хорошо определяет сообщения с нецензурными словами и выражениями, но не всегда понимает смысл. Например, часто сообщения со словами ‘black’ и ‘feminizm’ попадали в токсичный класс. Хотелось исправить эту проблему и научиться лучше понимать смысл сообщений с помощью следующей версии классификатора.

Офлайн режим


Для того, чтобы лучше понимать смысл сообщений, можно использовать нейросетевые алгоритмы:

  • Эмбеддинги (Word2Vec, FastText)
  • Нейросети (CNN, RNN, LSTM)
  • Новые предобученные модели (ELMo, ULMFiT, BERT)

Обсудим некоторые из таких алгоритмов и как их можно использовать подробнее.

Word2Vec и FastText


Модели эмбеддингов позволяют получать векторные представления слов из текстов. Существует два типа Word2Vec: Skip-gram и CBOW (Continuous Bag of Words). В Skip-gram по слову предсказывается контекст, а в CBOW наоборот: по контексту предсказывается слово.
image
Такие модели обучаются на больших корпусах текстов и позволяют получить векторные представления слов из скрытого слоя обученной нейросети. Минус такой архитектуры в том, что модель обучается на ограниченном наборе слов, которые содержатся в корпусе. Это означает, что для всех слов, которых не было в корпусе текстов на этапе обучения, не будет эмбеддингов. А такая ситуация происходит часто, когда предобученные модели используются для своих задач: для части слов не будет эмбеддингов, соответственно большое количество полезной информации будет теряться.

Для решения проблемы со словами, которых нет в словаре, (OOV, out-of-vocabulary) есть улучшенная модель эмбеддингов — FastText. Вместо использования отдельных слов для обучения нейросети, FastText разбивает слова на n-грамы (подслова) и обучается на них. Для получения векторного представления слова нужно получить векторные представления n-грам этого слова и сложить их.

Таким образом, для получения векторов признаков из сообщений можно использовать предобученные модели Word2Vec и FastText. Полученные признаки можно классифицировать с помощью классических ML классификаторов или полносвязной нейросети.

image
Пример вывода “ближайших” по смыслу слов с использованием предобученного FastText

Классификатор на CNN


Для обработки и классификации текстов из нейросетевых алгоритмов чаще используют рекуррентные сети (LSTM, GRU), так как они хорошо работают с последовательностями. Сверточные сети (CNN) чаще всего используют для обработки изображений, однако их также можно использовать в задаче классификации текстов. Рассмотрим, как это можно сделать.
Каждое сообщение представляет собой матрицу, в которой на каждой строке для токена (слова) записано его векторное представление. Свертка применяется к такой матрице определенным образом: фильтр свертки “скользит” по целым строкам матрицы (векторам слов), но при этом захватывает несколько слов за раз (обычно 2-5 слов), таким образом обрабатывая слова в контексте соседних слов. Подробно, как это происходит, можно посмотреть на картинке.
image
Зачем же применять сверточные сети для обработки текстов, когда можно использовать рекуррентные? Дело в том, что свертки работают сильно быстрее. Используя их для задачи классификации сообщений, можно сильно сэкономить время на обучении.

ELMo


ELMo (Embeddings from Language Models) — модель эмбеддингов на основе языковой модели, которая была недавно представлена. Новая модель эмбеддингов отличается от Word2Vec и FastText моделей. Вектора слов ELMo обладают определенными преимуществами:

  • Представление каждого слова зависит от всего контекста, в котором оно используется.
  • Представление основано на символах, что позволяет формировать надежные представления для OOV (out-of-vocabulary) слов.


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

Особенности реализации


API на Flask


Прототип API был написан на Flask, так как он прост в использовании.

Два Docker образа


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

Тестирование


Особенность реализации довольно большого числа алгоритмов машинного обучения состоит в том, что даже при высоких значениях метрик на валидационном датасете реальное качество алгоритма в продакшне может быть низкое. Поэтому для тестирования работы алгоритма всей командой использовали бота в Slack. Это очень удобно, потому что любой член команды может проверить, какой ответ выдают алгоритмы на определенное сообщение. Такой способ тестирования позволяет сразу увидеть, как будут работать алгоритмы на живых данных.
Хорошей альтернативой является запуск решения на публичных площадках вроде Яндекс Толоки и AWS Mechanical Turk.

Заключение


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

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


Конечно, мы выложили открытое демо Poteha Toxic Comment Detection в фейсбук боте. Помогите нам сделать бота лучше!

Буду рад ответить на вопросы в комментариях.
Теги:
Хабы:
Всего голосов 11: ↑11 и ↓0+11
Комментарии19

Публикации

Истории

Работа

Data Scientist
61 вакансия
Python разработчик
138 вакансий

Ближайшие события