Исходный код: https://github.com/djquigon/financial-sentiment-analysis

Измерение финансовых настроений — чрезвычайно мощный инструмент, которым можно пользоваться. Люди могут накопить миллионы и даже миллиарды долларов, умея правильно определять время рыночных циклов. Рыночные циклы определяются многими факторами, некоторые из которых очень трудно предугадать. Однако есть один фактор, который всегда предсказуем, — это страх и жадность розничных инвесторов. Возможность оценить, насколько боязливы, жадны или нейтральны розничные инвесторы в определенный момент времени, позволила бы узнать, должны ли они сами быть бычьими, медвежьими или оставаться в стороне. Одним из возможных способов расшифровки настроений в розничной торговле может быть анализ настроений в текущих финансовых заголовках. Используя рекуррентную нейронную сеть (RNN) и набор данных финансовых заголовков, ориентированных на розничных инвесторов, я решил воплотить эту идею в жизнь. Хотя чтение настроений в заголовках может быть не совсем надежным способом оценки настроений розничных инвесторов, оно, по крайней мере, имеет некоторые преимущества. Заголовки постоянно двигают рынки, будь то выпуск положительной или отрицательной квартальной отчетности по конкретной компании или сообщения об улучшении отношений или усилении трений между соперничающими экономиками. Вот ссылка на набор данных, который я использовал на Kaggle:



Он содержит CSV-файл с 4846 финансовыми заголовками в виде текста, каждый из которых связан с отрицательным, нейтральным или положительным настроением. Как и в предыдущем мини-проекте, я использую тензорный поток для создания своей RNN с использованием закрытого рекуррентного блока (GRU). Все это отдельно от модуля Keras, который можно найти здесь:



Конкретные параметры, используемые в моей RNN, наряду с упрощенным пошаговым описанием того, как работает GRU в RNN, можно найти в разделе 3. Результаты первых вариантов моей RNN не были столь многообещающими, как предсказания, сделанные были примерно такими же точными, как случайная догадка, принимая во внимание самые распространенные настроения. Однако после того, как я немного поработал и внес несколько модификаций, мои результаты стали намного более многообещающими, так как моя модель делала правильные прогнозы примерно в 73% случаев.

1. Введение

2. ДанныеПредварительная обработка

Как я уже говорил, набор данных, который я использовал, был опубликован пользователем Ankur Sinha на Kaggle, веб-сайте сообщества специалистов по данным, где пользователи могут публиковать свои собственные наборы данных и проекты машинного обучения. Он содержит CSV-файл из 4846 финансовых заголовков с соответствующими метками настроений: положительными, отрицательными или нейтральными. Анкур на самом деле не дает никакого конкретного вдохновения для сбора набора данных, он только описывает, что он содержит «настроения для заголовков финансовых новостей с точки зрения розничного инвестора». Ниже приведены значения для каждого ярлыка тональности:

Чтобы правильно отформатировать эти данные для передачи в RNN, я сначала добавил строку заголовка в CSV-файл, чтобы указать настроение и заголовок в качестве имен для двух столбцов. поскольку Анкур не включил это в исходный файл csv. Затем я создал фрейм данных pandas из CSV-файла, используя метод read_csv. Для того чтобы RNN могла обрабатывать заголовки, каждое слово в заголовке необходимо преобразовать в соответствующее целочисленное значение, которое затем можно использовать для преобразования заголовков в последовательности токенов. Используя результирующий фрейм данных из предыдущего шага, я токенизировал слова в заголовках с помощью объекта keras.preprocessing.text.Tokenizer() и вызывая fit_on_texts, передавая в headlineseriesиз фрейма данных в качестве параметра. Это выполняет большую часть тяжелой работы по необходимой предварительной обработке, поскольку создает индекс всех слов в заголовках и связанных с ними целочисленных значений, которые затем можно использовать для преобразования исходных текстов в последовательности этих целочисленных значений, представляющих слова с помощью вызов метода keras.preprocessing.text.Tokenizer()объектаtexts_to_sequences еще раз с передачей headlineсериииз фрейм данных в качестве параметра. Оттуда я дополнил последовательности, чтобы убедиться, что они имеют одинаковую длину. Наконец, Tensorflow требует, чтобы метки для модели были целыми числами, поэтому я предоставил сопоставление для различных настроений, где отрицательное равно 0, положительное равно 1 и нейтральное равно 2, и вызвал метод replace() для Столбец настроение из фрейма данных, передаваемый в моем сопоставлении в качестве параметра. Когда все это было завершено, я использовал sklearn.model_selection.train_test_split для создания наборов для обучения и тестирования, используя train_size, равный 0,7.

3. Эксперименты

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

В 2005 году объем продаж компании составил 187 млн евро.

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

Для запуска RNN будет принимать по одному слову, начиная с «The»:

RNN кодирует «The» и выдает результат. На следующем шаге вводится слово «фирма» вместе со скрытым состоянием из предыдущего шага. Скрытое состояние хранит информацию со всех предыдущих шагов, т.е. просто «The» в данном случае.

Этот процесс повторяется до тех пор, пока не будут обработаны все слова.

(1 / количество) * (всего) / 2,0

Примечание. Масштабирование по итогу / 2,0 помогает сохранить потери на том же уровне

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

4. Анализ и выводы

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

Первоначальная модель была несколько неудачной, фактически она была примерно эквивалентна случайному предположению. Если вы посмотрите на количество нейтральных заголовков, приведенное в таблице 2, соотношение нейтральных заголовков к общему количеству заголовков составляет примерно 59 %. Таким образом, если бы модель каждый раз просто предсказывала нейтральность, точность была бы примерно такой же. Очевидно, это был довольно нежелательный результат, и именно поэтому я вернулся и внес те изменения, которые я сделал. Результаты обновленной модели были намного больше похожи на результаты, которые я искал. Что меня больше всего поразило в результатах обновленных моделей, так это незначительная разница в точности между моделью с заданными весами и без них. Это означает, что даже с учетом дисбаланса между настроениями, который устраняет возможность чего-то вроде случайных предположений нейтрального искажения результатов, модель по-прежнему работала примерно одинаково. Несмотря на то, что ~ 73–74% было немного меньше, чем цель точности, которую я изначально установил на уровне 75%, я чувствовал, что этих результатов для меня достаточно. Конечно, всегда есть место для улучшения, и я планирую предоставить этой модели еще больше данных для обучения в свое личное время, а также внести изменения, чтобы улучшить ее, где это возможно. Поскольку я упомянул, что социальные сети являются движущей силой на рынках в современном обществе, я думаю, что могу попытаться собрать свой собственный набор данных твитов от людей из «крипто-твиттера», за которыми я слежу, которых я обсуждал ранее, и попытаться выполнить аналогичный анализ настроений по этим людям. твиты. Информация, которую я мог бы получить, была бы очень ценной для меня на одном из самых изменчивых и цикличных существующих рынков.

Финансовый анализ настроений с использованием рекуррентной нейронной сети

Исходный код: https://github.com/djquigon/financial-sentiment-analysis