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

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

Справочная информация об обнаружении троллей и ботов

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

На тему обнаружения ботов было проведено несколько исследований. Например, один исследователь обнаружил в Твиттере конкурирующих ботов против Трампа и против Трампа. Исследователи из Университета Индианы предоставили инструмент для проверки пользователей Twitter под названием botornot.

Также были проведены интересные исследования онлайн-троллей. Исследование Стэнфордского университета показало, что только 1% аккаунтов создает 74% конфликтов. Исследователи из Технологического института Джорджии использовали модель обработки естественного языка для выявления пользователей, которые нарушают нормы таким поведением, как личные нападки, женоненавистнические оскорбления или даже проступки.

Проверка комментариев на модерацию

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

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

Попробуйте сами на reddit-dashboard.herokuapp.com.

Чтобы оправдать ваши ожидания, наша система разработана как доказательство концепции. Это не производственная система, и она не на 100% точна. Мы будем использовать его, чтобы проиллюстрировать этапы построения системы, надеясь, что поставщики платформ смогут предлагать подобные официальные инструменты в будущем.

Сбор обучающих данных

Наш исходный набор данных для обучения был собран из списка известных ботов и троллей. Мы будем использовать два списка этих 393 известных ботов плюс еще 167 из сабреддита botwatch. Мы также воспользуемся списком из 944 аккаунтов троллей из Отчета о прозрачности Reddit за 2017 год, подозреваемых в работе на Российское агентство интернет-исследований.

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

Хотя комментарии Reddit не являются конфиденциальными, у вас могут быть конфиденциальные данные. Например, у вас могут быть данные, которые регулируются HIPAA или PCI или важны для вашего бизнеса или клиентов. Мы следовали эталонной архитектуре Heroku, которая была разработана для защиты личных данных. Он предоставляет сценарий Terraform для автоматической настройки хранилища данных Redshift и подключения его к частному пространству Heroku. В результате только приложения, работающие в частном пространстве, могут получить доступ к данным.

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

heroku run bash -a kafka-stream-viz-jorge
export PGPASSWORD=<password>
echo “select * from reddit_comments” | psql -h tf-jorge-tf-redshift-cluster.coguuscncu3p.us-east-1.redshift.amazonaws.com -U jorge -d redshift_jorge -p 5439 -A -o reddit.csv
gzip reddit.csv
curl -F “[email protected]https://file.io

Если вы предпочитаете использовать наши тренировочные данные, чтобы попробовать это самостоятельно, вы можете загрузить наш CSV.

Теперь у нас есть комментарии от обеих групп пользователей, их всего 93 668. Соотношения между классами фиксированы и составляют 5% троллей, 10% ботов и 85% обычных. Это полезно для обучения, но, вероятно, недооценивает истинный процент обычных пользователей.

Выбор функций

Далее нам нужно выбрать функции для построения нашей модели. Reddit предоставляет десятки полей JSON для каждого пользователя и комментария. У некоторых нет значимых ценностей. Например, banned_by было пустым во всех случаях, вероятно, потому, что у нас нет прав модератора. Мы выбрали поля ниже, потому что думали, что они могут быть полезны в качестве предикторов или для понимания того, насколько хорошо работает наша модель. Мы добавили столбец Recent_comments с массивом последних 20 комментариев, сделанных этим пользователем.

no_follow
link_id
gilded
author
author_verified
author_comment_karma
author_link_karma
num_comments
created_utc
score
over_18
body
is_submitter
controversiality
ups
is_bot
is_troll
recent_comments

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

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

recent_num_comments
recent_num_last_30_days
recent_avg_no_follow
recent_avg_gilded
recent_avg_responses
recent_percent_neg_score
recent_avg_score
recent_min_score
recent_avg_controversiality
recent_avg_ups
recent_avg_diff_ratio
recent_max_diff_ratio
recent_avg_sentiment_polarity
recent_min_sentiment_polarity

Для получения дополнительной информации о том, что это за поля и как они рассчитываются, см. Код в наших блокнотах Jupyter по адресу https://github.com/devspotlight/botidentification.

Построение модели машинного обучения

Наш следующий шаг - создать новую модель машинного обучения на основе этого списка. Мы будем использовать превосходный фреймворк Python scikit learn для построения нашей модели. Мы будем хранить наши обучающие данные в двух фреймах данных: один для набора функций для обучения, а второй - с желаемыми метками классов. Затем мы разделим наш набор данных на 70% данных обучения и 30% данных тестирования.

X_train, X_test, y_train, y_test = train_test_split(
 input_x, input_y,
 test_size=0.3, random_state=16)

Затем мы создадим классификатор дерева решений, чтобы предсказать, является ли каждый комментарий ботом, троллем или обычным пользователем. Мы будем использовать дерево решений, потому что созданное правило очень легко понять. Точность, вероятно, можно было бы повысить, используя более надежный алгоритм, такой как случайный лес, но мы будем придерживаться дерева решений, чтобы наш пример оставался простым.

clf = DecisionTreeClassifier(max_depth=3,
  class_weight={‘normal’:1, ‘bot’:2.5, ‘troll’:5},
  min_samples_leaf=100)

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

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

matrix = pd.crosstab(y_true, y_pred, rownames=[‘True’], colnames=[‘Predicted’], margins=True)

Это создаст матрицу путаницы, показывающую для каждой истинной целевой метки, сколько комментариев было предсказано правильно или неправильно. Например, ниже мы видим, что из 1956 комментариев троллей мы правильно предсказали 1451.

Predicted    bot        normal    troll        All
True                                 
bot          3677       585       33           4295
normal       197        20593     993          21783
troll        5          500       1451        1956
All          3879       21678     2477        28034

Другими словами, отзыв для троллей составляет 74%. Точность ниже; из всех комментариев, предположительно относящихся к троллям, на самом деле таковыми являются только 58%.

Recall : [0.85611176 0.94537024 0.74182004]
Precision: [0.94792472 0.94994926 0.58578926]
Accuracy: 0.917493044160662

Мы можем рассчитать общую точность 91,7%. Модель показала наилучшие результаты для обычных пользователей с точностью и отзывчивостью около 95%. Он работал довольно хорошо для ботов, но ему было труднее отличить троллей от обычных пользователей. В целом результаты выглядят довольно хорошо даже с довольно простой моделью.

Что говорит нам модель?

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

feature_imp = pd.Series(
 clf.feature_importances_,
 index=my_data.columns.drop(‘target’)).sort_values(ascending=False)
recent_avg_diff_ratio 0.465169
author_comment_karma 0.329354
author_link_karma 0.099974
recent_avg_responses 0.098622
author_verified 0.006882
recent_min_sentiment_polarity 0.000000
recent_avg_no_follow 0.000000
over_18 0.000000
is_submitter 0.000000
recent_num_comments 0.000000
recent_num_last_30_days 0.000000
recent_avg_gilded 0.000000
recent_avg_sentiment_polarity 0.000000
recent_percent_neg_score 0.000000
recent_avg_score 0.000000
recent_min_score 0.000000
recent_avg_controversiality 0.000000
recent_avg_ups 0.000000
recent_max_diff_ratio 0.000000
no_follow 0.000000

Интересный! Самой важной особенностью был средний коэффициент разницы в тексте недавних комментариев. Это означает, что если текст последних 20 комментариев очень похож, вероятно, это бот. Следующими по важности характеристиками были карма комментариев, карма ссылок, количество ответов на последние комментарии и подтверждена ли учетная запись.

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

Давайте посмотрим на реальное дерево решений, чтобы получить больше информации.

export_graphviz(estimator, out_file=’tree.dot’,
 feature_names = data.drop([‘target’], axis=1).columns.values,
 class_names = np.array([‘normal’,’bot’,’troll’]),
 rounded = False, proportion = False, 
 precision = 5, filled = True)

Теперь мы можем понять, как работает эта модель! Возможно, вам придется увеличить масштаб, чтобы увидеть детали.

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

Хостинг API

Чтобы сделать нашу модель машинного обучения доступной для всего мира, нам необходимо сделать ее доступной для нашей панели инструментов модератора. Мы можем сделать это, разместив API для вызова панели управления.

Для обслуживания нашего API мы использовали Flask, легкий веб-фреймворк для Python. Когда мы загружаем нашу модель машинного обучения, сервер запускается. Когда он получает запрос POST, содержащий объект JSON с данными комментария, он отвечает предсказанием.

Пример для пользователя бота:

{
 “banned_by”:null,
 “no_follow”:true,
 “link_id”:”t3_aqtwe1",
 “gilded”:false,
 “author”:”AutoModerator”,
 “author_verified”:false,
 “author_comment_karma”:445850.0,
 “author_link_karma”:1778.0,
 “num_comments”:1.0,
 “created_utc”:1550213389.0,
 “score”:1.0,
 “over_18”:false,
 “body”:”Hey, thanks for posting at \\/r\\/SwitchHaxing! Unfortunately your comment has been removed due to rule 6; please post questions in the stickied Q&amp;A thread.If you believe this is an error, please contact us via modmail and well sort it out.*I am a bot”,
 “downs”:0.0,
 “is_submitter”:false,
 “num_reports”:null,
 “controversiality”:0.0,
 “quarantine”:”false”,
 “ups”:1.0,
 “is_bot”:true,
 “is_troll”:false,
 “recent_comments”:”[…array of 20 recent comments…]”
}

Возвращенный ответ:

{
 “prediction”: “Is a bot user”
}

Мы развернули наш API на Heroku, потому что с ним очень легко работать. Мы просто создаем Procfile с единственной строкой, сообщающей Heroku, какой файл использовать для веб-сервера.

web: python app.py ${port}

Затем мы можем git отправить наш код в heroku:

git push heroku master

Heroku берет на себя заботу о загрузке требований, создании API, настройке веб-сервера, маршрутизации и т. Д. Теперь мы можем получить доступ к нашему API по этому URL-адресу и использовать Postman для отправки тестового запроса:

Https://botidentification.herokuapp.com/

Смотрите, как это работает

Благодаря великолепной панели инструментов модератора, которую мы написали в первой части этой серии, теперь мы можем видеть производительность нашей модели, основываясь на реальных комментариях. Если вы еще этого не сделали, проверьте это здесь: reddit-dashboard.herokuapp.com.

Он транслирует настоящие живые комментарии из сабреддита r / policy. Вы можете увидеть каждый комментарий и оценить, оценила ли его модель как бот, тролль или обычный пользователь.

Вы можете увидеть некоторые комментарии, помеченные как боты или тролли, но после просмотра истории их комментариев становится непонятно почему. Имейте в виду, что мы использовали простую модель, чтобы упростить изучение нашего руководства. Точность маркировки троллей составляет всего 58%. Вот почему мы разработали его как фильтр для просмотра модераторами-людьми.

Если вы хотите поиграть с этой моделью самостоятельно, посмотрите код на GitHub по адресу https://github.com/devspotlight/botidentification. Вы можете попробовать повысить точность модели, используя более сложный алгоритм, например случайный лес. Предупреждение о спойлере: можно получить более 95% точности тестовых данных с помощью более сложных моделей, но мы оставим это в качестве упражнения для вас.