Попытка журналиста ввести математику в редакцию новостей при анализе QAnon

На прошлой неделе я опубликовал Хронология QAnon: четыре года, 5000 падений и бесчисленное количество провальных пророчеств. Это расследование было проведено в сотрудничестве с Bellingcat - отделом новостей, который заново изобретает журналистские расследования с инновационными сообщениями с открытым исходным кодом и данными, недавно опубликованными в New York Times, WSJ, Financial Times, Washington Post и т. Д.

Я получил невероятное количество отзывов от коллег из сообщества разработчиков ПО, а также от специалистов по данным и журналистов.

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

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

Начало работы с данными 🍕

Расследование QAnon было сосредоточено на наборе данных, содержащем 4952 так называемых «Q-капель», загадочных сообщений, которые лежат в основе теории заговора. Их разместил аноним, известный просто как «Q», которого последователи считают источником инсайдерской информации о политике США. Всякий раз, когда появляется капля Q, верующие во всем мире нетерпеливо пытаются интерпретировать ее скрытый смысл, связывая их с событиями реального мира.

Набор данных Q drop был найден на доске изображений 8kun, которую последователи Q использовали как место для комментариев по Q drop. Он содержит сообщения, относящиеся к октябрю 2017 года, времени, когда теории QAnon были второстепенным онлайн-хобби, и продолжается до октября 2020 года, когда к ним относились слишком серьезно.

Методология

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

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

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

Q капли с одинаковым значением имеют похожие векторы. Близость двух векторов можно вычислить, взяв их скалярное произведение. Таким образом, мы смогли оценить «близость» тональности между предложениями, чтобы классифицировать текст каждой капли Q.

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

  1. Разделение данных на разделы
  2. Анализ настроений
  3. Алгоритмическая кластеризация

1) Разделение данных 🐼🐍

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

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

🐍 Для запуска языка программирования Python я предпочитаю PyCharm, но многие специалисты по данным также предпочитают Jupyter Notebook.

🐼 Pandas - широко популярная и сверхмощная библиотека анализа данных для Python.

Если вас интересует введение в учебник Pandas, в котором рассказывается об импорте набора данных и очистке данных, вот хороший ресурс от Towards Data Science. В противном случае еще одна причина, по которой я рекомендую Pandas для любой задачи анализа данных, - это его невероятно мощная функция Groupby.

Функция Groupby в Pandas позволяет нам взять фрейм данных (набор данных в Pandas) и легко разделить его на подмножества на основе атрибута.

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

2) Анализ настроений

Трудно работать со словами - мы предпочли бы числа! (не сказал ни один другой журналист, но это очень верно для целей анализа настроений.)

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

Итак, как мы это сделаем?

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

а) обучить нашу собственную модель встраивания слов на основе данных, связанных с Qanon.

б) позаимствовать чужую модель встраивания слов для преобразования текста в числа.

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

🦜 Руководство по использованию универсального кодировщика предложений

from absl import logging
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
tf.compat.v1.disable_eager_execution()

embed = hub.Module("https://tfhub.dev/google/universal-sentence-encoder/1")

paragraph1 = (
    "I am a sentence for which I would like to get its embedding."
    "Universal Sentence Encoder embeddings also support short paragraphs. "
    "There is no hard limit on how long the paragraph is. Roughly, the longer "
    "the more 'diluted' the embedding will be.")

paragraph2 = "There are Puppets. There are Puppet Masters. Which is MUELLER?"

messages = [paragraph1, paragraph2]

with tf.Session() as session:
  session.run([tf.global_variables_initializer(), tf.tables_initializer()])
  message_embeddings = session.run(embed(messages))

  for i, message_embedding in enumerate(np.array(message_embeddings).tolist()):
    print("Message: {}".format(messages[i]))
    print("Embedding size: {}".format(len(message_embedding)))
    message_embedding_snippet = ", ".join(
        (str(x) for x in message_embedding[:3]))
    print("Embedding: [{},...]\n".format(message_embedding_snippet))

В приведенном выше фрагменте мы сначала импортируем TensorFlow, популярную библиотеку машинного обучения Python, разработанную Google.

Следующий раздел кода взят из руководства Universal Sentence Encoder, где в строке 8 мы загружаем из Интернета модуль «embed», который берет наш входной текст и преобразует его в вектор, список из 512 чисел. Выходные данные содержатся в переменной message_embeddings, которую мы можем использовать для анализа и экспорта данных в таблицу Excel.

3) Объединение вещей вместе

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

Найти скалярное произведение двух векторов в Python очень просто:

import numpy as np
print(np.dot(a, b))

Разжигание тепла [Карта]

Давайте посмотрим на пример всего этого в действии! Ниже у нас есть 10 предложений из Q drop. Пятеро из них связаны с Робертом Мюллером, а пятеро связаны с Facebook.

Список из 10 предложений:

Мюллер1: «Есть марионетки. Есть Мастера кукол. Что такое [МЮЛЛЕР]? »,
Мюллер2:« Попытка заменить [JC] в качестве директора ФБР НЕУДАЛАСЬ [попытка восстановить контроль ФБР] »,
Мюллер3:« [МЮЛЛЕР] [Эпштейн похоронит и прикрывает -вверх]. »,
Мюллер4:« [МЮЛЛЕР] [заговор с целью удаления должным образом избранного ПОТУСА]. »,
Мюллер5:« САМЫЙ СКАНДАЛ В АМЕРИКАНСКОЙ ИСТОРИИ. TREASON. »,
Facebook1:« Что такое FB? »,
Facebook2:« Инструмент шпионажа? »,
Facebook3:« Кто его создал? »,
Facebook4:« Кто действительно создал это? »,
Facebook5:« Все не так, как кажется ».

Используя тепловую карту, созданную с помощью библиотеки Seaborn на Python, мы можем визуализировать скалярное произведение каждой пары предложений по шкале от 0 до 1. Диагональ полностью темно-красная, потому что каждая капля идентична самой себе. Обратите внимание, что верхний левый угол в основном оранжевый, поскольку предложения Мюллера больше коррелированы друг с другом, а предложения Facebook почти не связаны, кроме FB3 (Кто это создал) и FB4 (Кто на самом деле это создал), которые очень похожи и окрашены в красный цвет.

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

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

from sklearn.cluster import AgglomerativeClustering
import pandas as pd
import os

CSV_Path = os.path.join('data.csv')
df = pd.read_csv(CSV_Path)

arr = df.iloc[:,1].to_numpy()
vector = df.iloc[:,3].to_numpy()
dates = df.iloc[:,0].to_numpy()

dates = dates.tolist()[0:200]
sentences = arr.tolist()[0:200]
vector = vector.tolist()[0:200]

for i in range (len(vector)):
    vector[i] = vector[i][1:-1].split()

clustering = AgglomerativeClustering(n_clusters=3).fit(vector)
print(clustering.labels_)

Мы упрощаем указание количества кластеров, которое нам нужно, и запускаем алгоритм на подмножестве Q отбрасываний. Обычно мне нравится изменять количество кластеров в зависимости от количества падений в подмножестве. Это одно из ограничений этого алгоритма, при котором другой алгоритм кластеризации, такой как KD means, может лучше предсказать наилучшее количество кластеров для набора данных.

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

Вот ссылка на конечный продукт, результат этой методологии исследования выпадений Q: 🍕 Временная шкала Qanon: четыре года, 5000 падений и бесчисленное количество неудачных пророчеств.

Спасибо за внимание! В настоящее время я работаю исследователем открытых источников в BBC Africa Eye и внештатным журналистом данных. Вы также можете подписаться на мою новостную рассылку Brackets, чтобы еженедельно погружаться в зарождающееся пересечение технологий, данных и журналистики. Если у вас есть какие-либо вопросы или комментарии, не стесняйтесь обращаться ко мне напрямую в Twitter @ edward_the6.