Каждый сервис, чьи пользователи могут создавать собственный контент (UGC — User-generated content), вынужден не только решать бизнес-задачи, но и наводить порядок в UGC. Плохая или некачественная модерация контента в итоге может уменьшить привлекательность сервиса для пользователей, вплоть до прекращения его работы.
Сегодня мы вам расскажем про синергию между Юлой и Одноклассниками, которая помогает нам эффективно модерировать объявления в Юле.
Синергия вообще штука очень полезная, а в современном мире, когда технологии и тренды меняются очень быстро, она может превратиться в палочку-выручалочку. Зачем тратить дефицитные ресурсы и время на изобретение того, что до тебя уже изобрели и довели до ума?
Так же подумали и мы, когда перед нами во весь рост встала задача модерации пользовательского контента — картинок, текста и ссылок. Наши пользователи каждый день загружают в Юлу миллионы единиц контента, и без автоматической обработки промодерировать все эти данные вручную вообще не реально.
Поэтому мы воспользовались уже готовой платформой модерации, которую к тому времени наши коллеги из Одноклассников допилили до состояния «почти совершенство».
Почему Одноклассники?
Ежедневно в социальную сеть приходят десятки миллионов пользователей, которые публикуют миллиарды единиц контента: от фотографий до видео и текстов. Платформа модерации Одноклассников помогает проверять очень большие объёмы данных и противодействовать спамерам и ботам.
Команда модерации ОК накопила очень большой опыт, поскольку совершенствует свой инструмент уже 12 лет. Важно, что они не только могли поделиться своими готовыми решениями, но и настроить архитектуру своей платформы под наши специфические задачи.
Дальше для краткости будем называть платформу модерации ОК просто «платформа».
Как всё устроено
Между Юлой и Одноклассниками обмен данными налажен через Apache Kafka.
Почему мы выбрали этот инструмент:
В Юле все объявления проходят постмодерацию, поэтому изначально синхронный ответ не требовался.
Если случится лютый абзац, и Юла или Одноклассники будут недоступны, в том числе из-за каких-нибудь пиковых нагрузок, то данные из Kafka никуда не пропадут и позже их можно будет дочитать.
Платформа уже была интегрирована с Kafka, поэтому большинство вопросов безопасности оказались решены.
На каждое созданное или измененное пользователем объявление в Юле формируется JSON с данными, который кладется в Kafka для последующей модерации. Из Kafka объявления загружаются в платформу, где по ним выносятся решения автоматически или вручную. Плохие объявления блокируются с указанием причины, а те, в которых платформа не нашла нарушений, помечаются как «хорошие». Затем все решения отправляются обратно в Юлу и применяются в сервисе.
В итоге, для Юлы всё сводится к простым действиям: отправить объявление в платформу Одноклассников и обратно получить резолюцию «ок», или почему не «ок».
Автоматическая обработка
Что происходит с объявлением после того, как оно попадает в платформу? Каждое объявление разбивается на несколько сущностей:
название,
описание,
фотографии,
выбранная пользователем категория и подкатегория объявления,
цена.
Затем по каждой сущности платформа проводит кластеризацию, чтобы найти дубликаты. Причём текст и фотографии кластеризуются по разным схемам.
Тексты перед кластеризацией нормализуются, чтобы выкинуть спецсимволы, измененные буквы и прочий мусор. Полученные данные разбиваются на N-граммы, каждая из которых хэшируется. В итоге получается множество уникальных хэшей. Схожесть между текстами считается по мере Жаккара между двумя получившимися множествами. Если схожесть больше пороговой, то тексты склеиваются в один кластер. Для ускорения поиска похожих кластеров используется MinHash и Locality-sensitive hashing.
Для фотографий придуманы различные варианты склейки изображений, от сравнения pHash картинок до поиска дубликатов с помощью нейронной сети.
Последний способ самый «суровый». Для обучения модели подбирались такие тройки изображений (N, A, P), в которых N не похож на А, а P — похож на А (является полудубликатом). Затем нейросеть училась делать так, чтобы A и P были максимально близки, а A и N — максимально далеки. Так получается меньше ложных срабатываний по сравнению с тем, чтобы просто взять эмбеддинги от предобученной сети.
Когда нейросеть получает на вход картинки, она для каждой из них генерирует N(128)-мерный вектор и делается запрос на оценку близости изображения. Далее рассчитывается порог, при котором близкие изображения считаются дубликатами.
Модель умеет мастерски находить спамеров, которые специально фотографируют один и тот же товар с разных ракурсов, чтобы обойти сравнение по pHash.
Пример спамерских фото, склеенных нейронной сетью как дубликаты.
На конечном этапе дубликаты объявлений ищутся одновременно и по тексту, и по изображению.
Если в кластере склеиваются два и более объявления, система запускает автоматическую блокировку, которая по определённым алгоритмам выбирает, какие дубликаты удалить, а какие оставить. Например, если у двух пользователей в объявлении одинаковые фотографии, то система заблокирует более свежее объявление.
После создания все кластеры проходят через ряд автоматических фильтров. Каждый фильтр выставляет кластеру количество очков (score): с какой вероятностью тот содержит угрозу, которую выявляет этот фильтр.
Например, система анализирует описание в объявлении и выбирает для него потенциальные категории. Затем берёт ту, у которой максимальная вероятность, и сравнивает с категорией, которую указал автор объявления. Если они не совпадают, объявление блокируется за неверную категорию. А поскольку мы добрые и честные, то прямо говорим пользователю, какую категорию ему нужно выбрать, чтобы объявление прошло модерацию.
Уведомление о блокировке за неправильную категорию.
В нашей платформе машинное обучение чувствует себя как дома. К примеру, с его помощью мы ищем в названиях и описаниях запрещенные в РФ товары. А модели нейронных сетей придирчиво «разглядывают» изображения, нет ли на них URL-адресов, спамерских текстов, телефонов и всё той же «запрещёнки».
Для случаев, когда запрещенный товар пытаются продать, замаскировав под что-то легальное, и при этом нет никакого текста ни в названии, ни в описании, мы используем тегирование изображений. Для каждого изображения могут быть проставлены до 11 тысяч различных тегов, описывающих, что находится на изображении.
Кальян пытаются продать, замаскировав его под самовар.
Параллельно со сложными фильтрами работают и простые, решающие очевидные задачи, связанные с текстом:
антимат;
детектор URL-адресов и телефонных номеров;
упоминание мессенджеров и других контактов;
заниженная цена;
объявления, в которых ничего не продаётся, и т.д.
Сегодня каждое объявление проходит через мелкое сито из более чем 50 автоматических фильтров, которые пытаются найти в объявлении что-то плохое.
Если ни один из детекторов не сработал, то в Юлу отправляется ответ, что с объявлением, «скорее всего», полный порядок. Мы этот ответ применяем у себя, и пользователям, которые подписались на продавца, приходит уведомление о появлении нового товара.
Уведомление о том, что у продавца появился новый товар.
В итоге, каждое объявление «обрастает» метаданными, часть из которых генерируется при создании объявления (IP-адрес автора, user-agent, платформа, геолокация и т.д.), а остальное — это score, выданные каждым фильтром.
Очереди объявлений
Когда объявление попадает в платформу, система кладёт его в одну из очередей. Каждая очередь формируется с помощью математической формулы, которая комбинирует метаданные объявления таким образом, чтобы обнаружить какой-нибудь плохой паттерн.
Например, можно создать очередь объявлений в категории «Сотовые телефоны» от пользователей Юлы якобы из Санкт-Петербурга, но при этом их IP-адреса из Москвы или других городов.
Пример объявлений, размещенных одним пользователем в разных городах.
Или можно формировать очереди на основе баллов, которые нейросеть присваивает объявлениям, расставляя их по убыванию.
Каждая очередь, согласно своей формуле, присваивает итоговый score объявлению. Дальше можно действовать по-разному:
указать пороговое значение, при котором объявление будет получать определенный тип блокировки;
все объявления в очереди отправить модераторам на ручную проверку;
или скомбинировать предыдущие варианты: указать порог автоматической блокировки и отправить модераторам те объявления, которые не достигли этого порога.
Зачем нужны эти очереди? Допустим, пользователь загрузил фотографию огнестрельного оружия. Нейросеть присваивает ей score от 95 до 100 и с 99-процентной точностью определяет, что на картинке оружие. Но если значение score ниже 95 %, точность модели начинает снижаться (такова особенность моделей нейросетей).
В результате формируется очередь на основе score модели, и те из объявлений, которые получили от 95 до 100, автоматически блокируются как «Запрещенный товар». Объявления с количеством баллов ниже 95 отправляются на ручную обработку модераторам.
Шоколадная Beretta с патронами. Только для ручной модерации! 🙂
Ручная модерация
На начало 2019 года около 94 % всех объявлений в Юле модерируются автоматически.
Если платформа не может определиться с какими-то объявлениями, то отправляет их на ручную модерацию. Одноклассники разработали собственный инструмент: в заданиях для модераторов сразу отображается вся необходимая информация для принятия быстрого решения — объявление годное или стоит его заблокировать с указанием причины.
А чтобы при ручной модерации не страдало качество сервиса, работа людей постоянно контролируется. Например, в потоке заданий модератору показываются «ловушки» — объявления, по которым уже есть готовые решения. Если решение модератора не совпадает с готовым, модератору засчитывают ошибку.
На проверку одного объявления модератор в среднем тратит 10 секунд. При этом количество ошибок составляет не более 0,5 % от всех проверенных объявлений.
Народная модерация
Коллеги из Одноклассников пошли ещё дальше, воспользовались «помощью зала»: написали для соцсети приложение-игру, в котором можно быстро размечать большое количество данных, выделяя какой-то плохой признак, — Модератор Одноклассников (https://ok.ru/app/moderator). Хороший способ воспользоваться помощью пользователей ОК, которые стараются сделать контент приятнее.
Игра, в которой пользователи отмечают фотографии, на которых есть номер телефона.
Любую очередь объявлений в платформе можно перенаправить в игру Модератор Одноклассников. Всё, что размечают пользователи игры, затем поступает внутренним модераторам на проверку. Такая схема позволяет блокировать объявления, по которым еще не созданы фильтры, и попутно создавать обучающие выборки.
Хранение результатов модерации
Мы сохраняем все принятые при модерации решения, чтобы потом не обрабатывать повторно те объявления, по которым уже выносили какое-то решение.
Ежедневно по объявлениям создаются миллионы кластеров. Со временем каждый кластер получает отметку «хороший» или «плохой». Каждое новое объявление или его редакция, попадая в кластер с отметкой, автоматически получает резолюцию самого кластера. Таких автоматических резолюций в сутки набегает около 20 тысяч.
Если в кластер не поступают новые объявления, он удаляется из памяти, а его хэш и решение записываются в Apache Cassandra.
Когда платформа получает новое объявление, то сначала пытается найти похожий кластер среди уже созданных и взять решение из него. Если такого кластера нет, платформа идёт в Cassandra и ищет там. Нашла? Отлично, применяет решение к кластеру и отправляет в Юлу. Таких «повторных» решений ежедневно набирается в среднем 70 тысяч — 8 % от общего количества.
Подводя итог
Мы пользуемся платформой модерации Одноклассников два с половиной года. Результаты нам нравятся:
Автоматически модерируем 94 % всех объявлений за сутки.
Стоимость модерации одного объявления снизили с 2 рублей до 7 копеек.
Благодаря готовому инструменту забыли о проблемах управления модераторами.
В 2,5 раза увеличили количество обработанных вручную объявлений при том же количестве модераторов и бюджете. Ещё и качество ручной модерации возросло за счет автоматизированного контроля, и колеблется в районе 0,5 % ошибок.
Оперативно покрываем фильтрами новые типы спама.
Быстро подключаем к модерации новые подразделения «Юла Вертикали». С 2017 года в Юле появились вертикали Недвижимости, Вакансии и Авто.