Мы все были там. Вы получили коллекцию твитов от неизвестного автора, и вам интересно: «Эти твиты написаны Дональдом Трампом?»

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

В этом посте я исследую: Может ли плотная нейронная сеть определить, является ли Дональд Трамп автором твита?

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

Эта техническая схема объясняет мое понимание машинного обучения и нейронных сетей вместе.

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

Давайте перефразируем мою проблему: «Эти твиты написаны президентом?» в форму, которую может удовлетворить волшебная шкатулка. т.е. я хочу, чтобы мои твиты были массивами чисел, а мой ответ (да или нет) - массивом чисел. Ответ прост: мне нужен одномерный массив из 1 элемента, где 0 означает «Нет», а 1 означает «Да». С твитами немного сложнее.

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

Я хочу сделать здесь своего рода стилометрию с использованием плотной нейронной сети. Я использую фразу «своего рода стилометрия», потому что все, что я буду делать, это определять, был ли текст написан Дональдом Трампом, я не буду выбирать автора, кроме как сказать «Верно» или «Неверно» на вопрос «Автор - Дональд Трамп?».

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

Из статьи на тему Пол, жанр и стиль письма я узнал, что на самом деле вполне возможно вывести характеристики автора на основе его стиля письма. В этой статье утверждается, что точность предсказаний авторов мужского или женского пола на основе атрибутов их письма составляет 80%. Основными шаблонами, которые они сочли предсказуемыми, были шаблоны в последовательностях частей речи, употребления местоимений и статей, таких как слово The. Угадайте, какой пол чаще использует местоимения? Правильно, сексистка, это женщины.

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

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

Я написал функцию, которая берет строку текста и конвертирует ее в «вектор» (то есть список) чисел. Эта функция имеет множество подфункций, каждая из которых добавляет еще одно число к растущему списку «результатов». Пример: первый элемент списка чисел - это количество символов в тексте, второй - количество слов и так далее. Я добавил счетчики для частоты символов, среднего и стандартного отклонения длины слова, длины предложения, количества сокращений и счетчика частоты для короткого списка «функциональных» слов, то есть слов, которые сигнализируют о грамматической взаимосвязи (например, «делать» или «есть»). »).

Я также добавил более сложные измерения, такие как подсчет частот для частей речи, которые можно определить с помощью Python Модуль набора средств естественного языка, Оценка читабельности Флеша-Кинкейда и другие оценки« читабельности », а также анализ тональности с помощью Вейдера NLTK. ”Анализатор настроений, чтобы разбить текст на то, насколько он был положительным, отрицательным и нейтральным, и добавил эти оценки в мой растущий список.

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

Насколько я понимаю, слои Dense предназначены для выяснения отношений между различными входными числами, а слои «Dropout» предназначены для случайного отбрасывания данных, что должно предотвратить тип переобучения модели, при котором модель платит слишком много. внимание к конкретным и не общим особенностям обучающих данных. Последний слой выводит один элемент с использованием сигмовидной функции активации для вывода числа от 0 до 1. Я интерпретирую 0 как означающий «Не написано Дональдом Трампом», а 1 как «Написано Дональдом Трампом».

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

Сначала я загрузил все твиты Трампа и все свои собственные твиты и потратил некоторое время, экспериментируя с различными архитектурами моделей, различными функциями потерь, количеством эпох обучения и т. Д. Наиболее важные конфигурации, которые я обнаружил, заключались в установке параметра «validation_split» в функции соответствия модели на 0,2 и использовании обратного вызова «EarlyStopping» для отслеживания потерь при проверке.

Конфигурация разделения проверки выделяет часть данных, в моем случае 20%, которые будут использоваться для проверки. Это означает, что мы обучаем модель только на 80% данных, а остальные 20% оставляем для проверки.

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

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

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

С разделением валидации и ранней остановкой я вскоре получил, как мне кажется, довольно хороший результат точности - точность 80%. Другими словами, если я помещу 100 твитов Дональда Трампа в свой волшебный ящик, то около 80 из них вернутся с пометкой «Трамп», а если я добавлю 100 собственных твитов, около 80% из них вернутся с пометкой «Трамп». Не Трамп ». Означает ли это, что у меня есть детектор Дональда Трампа с точностью 80%?

Ну, поскольку я немножко тупой, я сначала подумал, что это означает именно это. Я тестировал его на некоторых своих твитах и ​​некоторых твитах Трампа, и, похоже, он в основном работал. Захватывающе! Затем я протестировал его на нескольких случайных твитах, которые я взял из своей временной шкалы в твиттере, и обнаружил, что моя модель также была очень рада называть эти твиты Трампа. См .: В той же мере, в какой моя модель была детектором Трампа, она была детектором «не-я». Другой способ думать об этом заключается в том, что модель научилась предсказывать твиты Трампа, но только во вселенной, где Трамп составлял половину всех твитеров.

Поправкой для этого было получение большего количества данных. Еще больше твитов от еще большего количества людей, и я продолжаю тренироваться. Поначалу это тоже натолкнулось на серьезную проблему. Имея 100 не-козырей и только 1 козырь, модель может мгновенно стать точной на 99%, если просто всегда угадывать «не козырь». Модель действительно так и поступала, пока я не узнал, что есть конфигурация «class_weight =‘ auto ’», которую вы можете передать функции подбора. Эта конфигурация означает, что модель будет взвешивать различные классы обратно пропорционально их частоте - это означает, что класс «Трамп» был очень редким, только 1 из 101 входных данных был помечен как «Трамп», и поэтому твиты Трампа имели гораздо больший вес при обновлении. модель, чтобы сбалансировать редкость.

Это довольно быстро дошло до точки, когда моя производительность по сравнению с набором для проверки перестала улучшаться. Мое первоначальное намерение состояло в том, что выход 0,5 или больше будет моделью, утверждающей, что входные данные были твитом Трампа, а меньше 0,5 - моделью, утверждающей, что входные данные не были твитом Трампа. Я обнаружил, что модель буквально никогда не предсказывала Трампа по этому определению.

Я решил изменить то, как я думаю о выходе модели. Вместо того, чтобы брать 0,5 или выше, чтобы предсказать ярлык «Трампа», я просто посмотрел на все выходные данные для всех твитов Трампа и всех твитов, не связанных с Трампом. Я обнаружил, что твиты, не относящиеся к Трампу, имели среднее значение 0,0147, по сравнению со средним значением выходных данных твитов Трампа, которое составляло 0,2069.

В моей новой концепции выводом является «T-Score», просто представляющий, насколько вероятно, что твит будет автором Дональда Трампа. Чем выше оценка, тем больше вероятность, что автором является Трамп. Используя эту модель, вы действительно не можете посмотреть на один твит и даже уйти с очень высокой уверенностью, что автором был Трамп. Однако вы могли бы посмотреть на коллекцию твитов, написанных одним и тем же автором, и понять, что вы наблюдаете действительно необычно и постоянно высокие Т-баллы, а затем сделать вывод, что автором, вероятно, был Дональд Трамп.

По крайней мере, это была моя теория. Я обучил свою модель на 100 аккаунтах плюс Трамп. Чтобы проверить свою модель и свою теорию, я на порядок пошел дальше и просмотрел 1000 аккаунтов в Твиттере. Я выбрал 994 аккаунта наугад, затем добавил аккаунты Трампа, его детей, твиттер-аккаунт POTUS и Майка Пенса.

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

Затем для каждой учетной записи я загружаю все их твиты и передаю их модели для T-Scores. Для любой учетной записи с более чем пятью твитами я нахожу средний T-Score на твит для этой учетной записи. Затем я ранжирую все учетные записи по среднему T-баллу, нормализованному так, чтобы учетная запись с максимальным средним T-баллом равнялась 1, а последующие учетные записи имели средний T-балл, который является их долей от максимального.

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

  1. У Трампа самый высокий T-Score из всех протестированных аккаунтов.
  2. Счет «POTUS» входит в десятку лучших T-Scores.
  3. Фигуры, похожие на Трампа, представлены в первой десятке T-Scores.
  4. Т-балл Трампа (ненормированный средний) как минимум на 3 стандартных отклонения выше среднего среднего Т-балла.

Из этих критериев мои результаты показали, что моя модель соответствует всем четырем.

  1. Средний T-Score Трампа был самым высоким из всех счетов. С окончательной моделью и всеми твитами Трампа средний T-Score Трампа составил 0,163.
  2. Счет POTUS, также, по крайней мере номинально, управляемый Трампом, оказался на третьем месте с оценкой 0,068.
  3. В топ-10 вошли «Trumphop» (аккаунт, ретвитнувший старые твиты Трампа), Майк Пенс, Кейли МакЭнани (пресс-секретарь Трампа), Райан Фурнье (основатель программы «Студенты Трампа»), Хоган Гидли (заместитель пресс-секретаря) и Христианско-консервативный счет сторонников Трампа «Американская семейная ассоциация». Другими словами, 6 из 10 ведущих аккаунтов были фигурами Трампа. Случайная выборка из моего списка учетных записей показывает, что это больше, чем можно было бы ожидать по случайной случайности.
  4. Стандартное отклонение T-Score составляло 0,009, а среднее T-Score - 0,015. Оценка Трампа 0,163 была на 16,4 стандартного отклонения выше среднего.
  5. (Бонус) Дональд Трамп-младший занял 29-е место, Иванка 34-е, Эрик 38. Все трое детей были в топ-40, то есть 95+ процентилей.

Моя модель сложилась не так, как я думал. То есть, он никогда не предсказывает, что твит был написан Трампом с результатом 0,5 или больше. Однако чем больше я думаю об этом, тем больше смысла в этом мне кажется - модель как бы «выросла» во вселенной со 101 твитером, и мне кажется вполне разумным, что в текстовых характеристиках нет закономерностей. Я использовал эту программу, чтобы вы могли на 50% больше уверенности в том, что данный твит был написан одним из 101 твитера. У Трампа своеобразный стиль твитов, но другие люди могут писать твиты с похожими характеристиками, и твиты Трампа тоже разные.

Тот факт, что твиттер-аккаунт Трампа получил наивысший T-Score из 1000, которую я использовал в своем последнем тесте, меня не удивил. Модель была в основном обучена на твитах Трампа, и, поэкспериментировав с набором из 100 твитеров, я понял, что она принесет Трампу гораздо больше очков, чем любой случайный человек.

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

Что я хотел бы сделать дальше с этим проектом, так это провести дополнительное тестирование, масштабирование на другой порядок, тестирование с 10 000 учетных записей Twitter и использование тех же 4 критериев, чтобы увидеть, продолжает ли модель работать хорошо. Я могу улучшить тест, взяв случайную выборку из 100 моих аккаунтов в Twitter и посчитав, какое количество из них связано с Трампом. Это позволило бы мне сказать, было ли 6 из 10 аккаунтов, связанных с Трампом, в топ-10, хорошим или плохим результатом.

Чтобы подняться еще на порядок выше, мне сначала нужно оптимизировать свой твит для работы с векторным кодом. На обработку 1 952 821 твита, использованного в моем последнем тесте, потребовалось около 24 часов и 4 ГБ ОЗУ. Я не хочу ждать 10 дней, чтобы увидеть результаты следующего теста. К счастью, я думаю, что могу легко сделать это многопоточным, чтобы использовать все мои ядра и хранить вещи на диске, а не полностью в памяти. Это позволило бы мне запустить 10-кратный тест примерно за то же время, что и исходный тест.

Я также видел создание веб-сайта, на котором использовался этот инструмент. Люди могли зайти на сайт, ввести имя твиттера и получить результат T-Score для имени твиттера.

У меня есть еще несколько идей, которыми можно заняться с этой моделью. Лучше всего сделать его более общим, чтобы он обнаруживал не Дональда Трампа, а кого-либо. Если это сработает, инструмент можно будет использовать для идентификации людей с учетными записями sockpuppet, потому что их sockpuppet должны иметь такие же «T-Scores», как и их реальные счета.

Я более чем счастлив поделиться своим кодом, моделью или данными, если кому-то интересно. На самом деле я не ожидаю, что кто-нибудь прочитает этот пост, тем не менее, не всю его, поэтому я не собираюсь беспокоиться о том, где и как загружать эти вещи, если кто-то не попросит об этом. Если вам интересно, вы можете увидеть 1 000 рейтингов T-Score здесь.

Спасибо!

P.S.

Несколько открытых загадок -

  1. Почему учетная запись Trumphop, которая репостит твиты Трампа, не имеет намного более высокого или идеального T-Score, поскольку она репостит Трампа? Я думаю, это связано с тем фактом, что ретвиты, читаемые API, всегда начинаются с фразы вроде «RT @realDonaldTrump:», которая может придавать им характеристики, отличные от оригинального Trump.
  2. Почему в моем списке из 1000 учетных записей всего 795? Некоторые учетные записи исключены из-за наличия менее 5 твитов. Также, похоже, была проблема с кодом загрузки моего твита, который не получал твиты для учетных записей, хотя я знаю, что у них более 5 твитов (я подозреваю, что срок действия токена в моем сценарии загрузки истек, а случайное количество учетных записей действительно не не скачивается).
  3. Предсказывает ли T-Score что-нибудь о политическом раскладе? Мне было интересно, что консервативные / трамповские цифры, похоже, были наверху. (Хотя это не всегда так - например, Гингрич находится в самом низу).