Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr

Содержание

Прогнозирование фондового рынка с использованием нейронных сетей / Habr


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

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


Рассмотрим на практике применение метода прогнозирования с помощью нейронных сетей. Для примера возьмём данные индекса ММВБ в период с 01.10.2008 по 03.04.2009. Задача состоит в том, что на основе представленной статистической информации необходимо сделать прогноз на 10 дней. Как видно из графика (рис.1), с 01.10.08 по 28.10.08 индекс ММВБ «просел» примерно на 534 пункта. После чего последовал рост до максимальной отметки в 871 пункт. Далее, некоторое время, рынок находился в боковом тренде, затем наметилась восходящая тенденция. В данном примере будем строить прогноз для одной переменной (остальные аналогично), но для того, чтобы выбрать ту из четырех переменных, которая наиболее сильно поможет спрогнозировать остальные, построим корреляционную матрицу.

Итак, построив матрицу парных корреляций (табл.1), делаем вывод о том, что переменная LOW наиболее сильно коррелирует с остальными. Займёмся прогнозом данной переменной.

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


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

В результате идентификации процесса построения сетей мы получили следующие результаты: выбранные сети, как можно заметить, имеют различные конфигурации (табл.2).

В результате обучения была найдена нейронная сеть, соответствующая модели 7 (рис.2) с хорошей производительностью (регрессионное отношение: 0,253628, ошибка: 0,003302). Нетрудно заметить, что производительность сетей с архитектурой Радиально Базисной Функции (РБФ) в среднем хуже производительности сетей с архитектурой Многослойно персептрона. Во многом это объясняется тем, что сети с архитектурой РБФ плохо экстраполируют данные (это связано с насыщением элементов скрытой структуры). Для оценки правдоподобности модели 7 построим гистограмму частот (рис.3). Данная гистограмма является самой симметричной по сравнению с другими моделями. Это подтверждает стандартные предположения о нормальности остатков. Следовательно, модель 7 больше всего подходит для данного временного ряда.

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

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


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


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

1. Э.А.Вуколов. Основы статистического анализа. Издательство «Форум», Москва

2008г.

2. В. Боровников. STATISTICA: искусство анализа данных на компьютере. 2003г.

3. Недосекин А.О. Нечетко-множественный анализ риска фондовых инвестиций. Изд.

Сезам, 2002г.

Ранее статья публиковалась в материалах 3-ей региональной научной конференции ВолгГТУ в 2009 году (Том 3).

Прогнозирование цен с помощью нейронных сетей


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

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


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

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

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

Это важнейшее свойство рыночных временных рядов легло в основу теории "эффективного" рынка, изложенной в диссертации Луи де Башелье (L.Bachelier) в 1900 г. Согласно этой доктрине, инвестор может надеяться лишь на среднюю доходность рынка, оцениваемую с помощью индексов, таких как Dow Jones или S&P500 для Нью-Йоркской биржи. Всякий же спекулятивный доход носит случайный характер и подобен азартной игре на деньги (а что то в этом есть, не находите?). В основе непредсказуемости рыночных кривых лежит та же причина, по которой деньги редко валяются на земле в людных местах: слишком много желающих их поднять.

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

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


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

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

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

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

Подготовка данных

Для начала работы нужно подготовить данные, от правильности этой работы зависит 80% успеха.

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


изменения котировок. Поскольку эти изменения, как правило, гораздо меньше по амплитуде, чем сами котировки, между последовательными значениями курсов имеется большая корреляция - наиболее вероятное значение курса в следующий момент равно его предыдущему значению C(t+1)=C(t)+delta(C)=C(t).

Между тем, для повышения качества обучения следует стремиться к статистической независимости входов, то есть к отсутствию подобных корреляций. Поэтому в качестве входных переменных логично выбирать наиболее статистически независимые величины, например, изменения котировок delta(С) или логарифм относительного приращения log(C(t)/C(t+1)).

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

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

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

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

Выбор программного обеспечения

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

1. Matlab – настольная лаборатория для математических вычислений, проектирования электрических схем и моделирования сложных систем. Имеет встроенный язык программирования и весьма богатый инструментарий для нейронных сетей – Anfis Editor (обучение, создание, тренировка и графический интерфейс), командный интерфейс для программного задания сетей, nnTool – для более тонкой конфигурации сети.

2. Statistica – мощнейшее обеспечение для анализа данных и поиска статистических закономерностей. В данном пакете работа с нейросетями представлена в модуле STATISTICA Neural Networks (сокращенно, ST Neural Networks, нейронно-сетевой пакет фирмы StatSoft), представляющий собой реализацию всего набора нейросетевых методов анализа данных.

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

4. NeuroShell Day Trader - нейросетевая система, которая учитывает специфические нужды трейдеров и достаточно легка в использовании. Программа является узкоспециализированной и как раз подходит для торговли, но по своей сути слишком близка к черному ящику.

5. Остальные программы являются менее распространенными.

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

Ознакомиться с комплексом MatLab можно в википедии https://ru.wikipedia.org/wiki/MATLAB

Много материалов по программе предоставлено на сайте http://matlab.exponenta.ru/

Приобрести программу можно через компанию SoftLine http://soft.softline.ru/author_page_all.php?id=410

Эксперимент

Подготовка данных

Данные очень удобно можно получить стандартными средствами MetaTrader:

Сервис -> Архив котировок -> Экспорт

В результате получаем файл в формате *.csv, который является первичным сырьем для подготовки данных. Для преобразования полученного файла в удобный для работы файл *.xls нужно произветси импорт данных из файла *.csv. Для этого в excel нужно произвести следующие махинации:

Данные -> Импорт внешних данных -> Импортировать данные и указать подготовленный первичный файл. В мастере импорта все необходимые действия выполняются в 3 шага:

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr


На 3 шаге необходимо поменять разделитель целой и дробной части на точку, делается это при нажатии кнопки Подробнее…

Для того чтобы данные были восприняты как цифры, а не как строки, нужно поменять разделитель целой и дробной части на точку:

Сервис -> Параметры -> Международные -> Разделитель целой и дробной части.

На скриншотах показан пример сохранения цен открытия и закрытия, остальные данные пока не нужны.

Теперь данные надо преобразовать в соответствии с тем, что и как мы хотим прогнозировать. Составим прогноз цены закрытия будущего дня по четырем предыдущим (данные идут в пяти столбцах, цены в хронологическом порядке).






1.2605

1.263

1.2641

1.2574

1.2584

1.2666

1.263

1.2641

1.2574

1.2584

1.2666

1.2569

1.2641

1.2574

1.2584

1.2666

1.2569

1.2506

1.2574

1.2584

1.2666

1.2569

1.2506

1.2586

1.2584

1.2666

1.2569

1.2506

1.2586

1.2574


Благодаря нехитрым манипуляциям в excel данные подготавливаются за пару минут. Пример подготовленного файла с данными можно взять в прикрепленых файлах.

Для того, чтобы Matlab распознал файлы, необходимо, чтобы подготовленные данные были сохранены в файлах с расширением *.txt или *.dat. Сохраним их в файлах *.txt. Далее каждый файл разбиваем на два множества – для обучения сети (выборка) и для ее тестирования (вне выборки). Подготовленные таким образом euro.zip данные пригодны для дальнейшей работы

Знакомство с Matlab

Из командной строки по команде anfisedit запускаем пакет ANFIS. Редактор состоит из четырех панелек – для данных (Load data), для генерации сети (Generate FIS), для тренировки (Train FIS)и для ее тестирования (Test FIS). Верхняя панель предназначена для просмотра структуры полученной нейросети (ANFIS Info).

Более подробно с работой пакета можно ознакомиться по приведенным ниже ссылкам.

http://forest.akadem.ru/library/matlab/fuzzylogic/book1/7_6.html

http://matlab.exponenta.ru/fuzzylogic/book1/1_7_5_7.php

Для начала работы загружаем данные, подготовленные на предыдущих этапах. Для этого нажимаем кнопку Load Data и указываем файл с данными выборки. После этого создаем нейросеть нажатием кнопки Generate FIS.

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr


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

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr


Для обучения нейросетей в пакете AnfisEdit предусмотрено 2 алгоритма обучения – обратного распространения и гибридный. При гибридном способе обучения сеть обучается буквально за пару-тройку проходов. На тренировочной выборке (60 значений) после обучения прогноз сети отличается от реального на несколько пунктов.

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr


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

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr

Результатом нашей работы является многослойная гибридная нейронная сеть, которая способна прогнозировать абсолютные значения цен на небольшой будущее. Она кардинально отличается своей архитектурой и целями от однослойной нейронной сети, представленной господином Решетовым в своей статье http://articles.mql4.com/ru/articles/1447 и реализованной в качестве эксперта https://www.mql5.com/ru/code/10289.

Нам удалось получить более-менее сносный прогноз по самим котировкам, хотя специалисты в области нейронных сетей настоятельно не рекомендуют делать это. Полученной нейросетью можно полюбоваться при нажатии кнопки Structure. Обученную нейросеть можно взять в прикрепленых файлах neuro.zip .

Нейронная сеть для прогнозирования: Прогнозирование фондового рынка с использованием нейронных сетей / Habr – Система прогнозирования на базе нейронных сетей в промышленности / Habr

Большим плюсом пакета MatLab является его интегрируемость с другими программами, причем существует множество вариантов его интреграции DDE, com-объекты, dll. Таким образом, можно не создавать инструмент с нуля https://www.mql5.com/ru/forum/102093, а воспользоваться готовым програмным решением для работы с нейронными сетями и генетическими алгоритмами. Затем, после получения стабильных результатов прогнозирования, можно будет интегрировать полученную нейросеть в программу MetaTrader через dll.

Заключение

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

Плюсом нейросетей является объективность при принятии решения, а минусом – то, что решение принимает фактически черный ящик.

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

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

Литература

1. Нейрокомпьютинг и его применение в науке и бизнесе. А. Ежов, С. Шумский. 1998 г

Прогнозирование финансовых временных рядов с MLP в Keras / Habr



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

Вступление

Я сейчас учусь на последнем курсе магистратуры в University of Verona по специальности "прикладная математика", и как типичный студент-айтишник из СНГ, работать начал еще на бакалаврате в Киевском Политехническом Институте, применяя тогда еще только набиравшее обороты машинное обучение в разных проектах, чем занимаюсь и сейчас. В университете тема моих исследований — deep learning применительно к временным рядам, в частности — финансовым.

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

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

Подготовка данных

Для примера возьмем цены акций такой скромной компании как Apple с 2005 по сегодняшний день. Их можно скачать на Yahoo Finance в формате .csv. Давайте загрузим данные и посмотрим как вся эта красота выглядит.

Для начала заимпортим нужные нам для загрузки библиотеки:

import matplotlib.pylab as plt
import numpy as np
import pandas as pd

Прочитаем данные и нарисуем графики (в .csv из Yahoo Finance данные загружены в обратном порядке — от 2017 до 2005, так что сначала надо их “перевернуть” с помощью [::-1]):

data = pd.read_csv('./data/AAPL.csv')[::-1]
close_price = data.ix[:, 'Adj Close'].tolist()
plt.plot(close_price)
plt.show()

image

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

Что в случае классификации, что в случае регрессии, на вход мы возьмем какое-то окно временного ряда (например, 30 дней) и постараемся или предсказать движение цены в следующий день (классификация), или значение изменения (регрессия).

Основная проблема финансовых временных рядов — они вообще ни капельки не стационарны (можете проверить сами с помощью, скажем, теста Дики-Фуллера), то есть их характеристики, как мат. ожидание, дисперсия, среднее максимальное и минимальное значение в окне меняются со временем, что значит, что по-хорошему мы не можем использовать эти значения для MinMax или z-score нормализации по нашим окнам, так как если в 30 дней в нашем окне у нас одни характеристики, но они могут измениться уже на следующий день или измениться посередине нашего окна.

Но если внимательно посмотреть на задачу классификации, нас не так интересует мат. ожидание или дисперсия в следующий день, нас интересует исключительно движение вверх или вниз. Поэтому мы рискнем, и будем нормализировать наши 30-дневные окна с помощью z-score, но только их, не затрагивая ничего из “будущего”:

X = [(np.array(x) - np.mean(x)) / np.std(x) for x in X]

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

close_price_diffs = close.price.pct_change()

image

выглядит это так, и как видим — эти данные, полученные без каких-то манипуляций с статистическими характеристиками уже лежат в пределе от -0.5 до 0.5:

Для разделения на обучающую и тренировочную выборку возьмем первые 85% окон во времени для обучения и последние 15% для проверки работы нейронной сети.

Так что для обучения нашей нейронной сети мы получим следующие пары X, Y: цены в момент закрытия рынка за 30 дней и [1, 0] или [0, 1] в зависимости от того, выросло или упало значение цены для бинарной классификации; процентное изменение цен за 30 дней и изменение на следующий день для регрессии.

Архитектура нейронной сети

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

В качестве фреймворка для имплементации возьмем Keras — он очень прост, интуитивно понятен и с ним можно реализовывать достаточно сложные вычислительные графы на коленке, но пока что нам это и не понадобится. Реализуем простенькую сетку — входной слой с 30 нейронами (длина нашего окна), первый скрытый слой с 64 нейронами, после него BatchNormalization — его рекомендуется использовать практически для любых многослойных сетей, потом активационная функция (ReLU уже считается не комильфо, поэтому возьмем что-то модное вроде LeakyReLU). На выходе разместим один нейрон (или два для классификации), который в зависимости от задачи (классификация или регрессия) будет или иметь softmax на выходе, или оставим его без нелинейности, чтобы иметь возможность прогнозировать любое значение.

Код для классификации выглядит так:

model = Sequential()
model.add(Dense(64, input_dim=30))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(2))
model.add(Activation('softmax'))

Для задачи регрессии в конце параметр активации должен быть ‘linear’. Далее нам нужно определить функции ошибки и алгоритм оптимизации. Не вдаваясь в детали вариаций градиентного спуска возьмем Adam с длиной шага 0.001; параметр loss для классификации нужно поставить кросс-энтропию — ‘categorical_crossentropy’, а для регрессии — среднюю квадратическую ошибку — ‘mse’. Также Keras позволяет нам достаточно гибко контролировать процесс обучения, например, хорошая практика — это уменьшать значение шага градиентного спуска, если наши результаты не улучшаются — именно этим и занимается ReduceLROnPlateau, который мы добавили как коллбэк в обучение модели.

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.9, patience=5, min_lr=0.000001, verbose=1)
model.compile(optimizer=opt, 
              loss='categorical_crossentropy',
              metrics=['accuracy'])

Обучение нейронной сети

history = model.fit(X_train, Y_train, 
          nb_epoch = 50, 
          batch_size = 128, 
          verbose=1, 
          validation_data=(X_test, Y_test),
          shuffle=True,
          callbacks=[reduce_lr])

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

plt.figure()
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='best')
plt.show()

plt.figure()
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel(‘acc’)
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='best')
plt.show()

Перед запуском обучения хочу обратить внимание на на важный момент: учить алгоритмы на таких данных надо подольше, хотя бы 50-100 эпох. Это связано с тем, что если вы обучите на, скажем, 5-10 эпохах и увидите 55% точности, это скорее всего не будет значить, что вы научились находить паттерны, если вы проведете анализ тренировочных данных, будет видно, что просто 55% окон были для одного паттерна (повышение, например), а остальные 45% — для другого (понижение). В нашем случае 53% окон класса “понижения”, а 47% — “повышения”, поэтому мы будем стараться получить точность выше 53%, которая и будет говорить о том, что мы научились находить признаки.

Слишком высокая точность на сырых данных вроде цены закрытия и простых алгоритмах скорее всего будет говорить о переобучении или “заглядывании” в будущее при подготовке обучающей выборки.

Задача классификации

Проведем обучение нашей первой модели и посмотрим на графики:

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

model = Sequential()
model.add(Dense(64, input_dim=30))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(16))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(2))
model.add(Activation('softmax'))

Вот результаты ее работы:

Приблизительно такая же картина. Когда мы сталкиваемся с эффектом переобучения, нам нужно добавить регуляризацию в нашу модель. Если вкратце, то во время переобучения мы строим модель, которая просто “запоминает” наши тренировочные данные и не позволяет обобщить знания на новые данные. В процессе регуляризации мы накладываем определенные ограничения на веса нейронной сети, чтобы не было большого разброса в значениях и не смотря на большое количество параметров (т.е. весов сети), часть из них обратить в ноль для упрощения. Мы начнем с самого распространенного способа — добавления к функции ошибки дополнительного слагаемого с L2 нормой по сумме весов, в Keras это делается с помощью keras.regularizers.activity_regularizer.

model = Sequential()
model.add(Dense(64, input_dim=30,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(16,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(2))
model.add(Activation('softmax'))

Такая нейронная сетка учится уже немного лучше с точки зрения функции ошибки, но точность все еще страдает:

Такой странный эффект как уменьшение ошибки, но не уменьшение точности нередко встречается при работе с данными большой зашумленности или случайной природы — это объясняется тем, что ошибка считается на основе значения cross-entropy, которое может уменьшаться во время того, как точность — это индекс нейрона с правильным ответом, который даже при изменении ошибки может оставаться неправильным.

Поэтому стоит добавить еще больше регуляризации в нашу модель с помощью популярной в последнии года техники Dropout — грубо говоря, это случайное “игнорирование” некоторых весов в процессе обучения, чтобы избежать ко-адаптации нейронов (чтобы они не выучивали одинаковые признаки). Код выглядит следующим образом:

model = Sequential()

model.add(Dense(64, input_dim=30,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dropout(0.5))
model.add(Dense(16,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(2))
model.add(Activation('softmax'))

Как видим, между двумя скрытыми слоями мы будем “дропать” связи во время обучения с вероятностью 50% для каждого веса. Дропаут обычно не добавляют между входным слоем и первым скрытым, так как в этом случае мы будем учить на просто-напросто зашумленных данных, и также не добавляется прямо перед выходом. Во время тестирования сети никакого дропаута, разумеется, не происходит. Как учится такая сетка:

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

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

Как видим, если мы остановим обучение достаточно рано (со временем все равно наступает оверфиттинг), то можем получить 60% точности, что очень даже неплохо.

Задача регрессии

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

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

pred = model.predict(np.array(X_test))
original = Y_test
predicted = pred

plt.plot(original, color='black', label = 'Original data')
plt.plot(predicted, color='blue', label = 'Predicted data')
plt.legend(loc='best')
plt.title('Actual and predicted')
plt.show()

Архитектура сети будет выглядеть следующим образом:

model = Sequential()
model.add(Dense(64, input_dim=30,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(16,
                activity_regularizer=regularizers.l2(0.01)))
model.add(BatchNormalization())
model.add(LeakyReLU())
model.add(Dense(1))
model.add(Activation('linear'))

Посмотрим что получится, если обучить на “сыром” adjustment close:

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

Если же обучить на изменениях цен, то получим следующие результаты:

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

Обсуждение

В принципе, на первый взгляд, результаты вообще не впечатляют. Так и есть, но мы обучили самый простой вид нейронной сети на одномерных данных без особой предобработки. Есть ряд шагов, которые позволяют вывести точность на уровень 60-70%:

  • Обучать на высокочастотных данных (каждый час, каждые пять минут) — больше данных — больше паттернов — меньше переобучения
  • Использовать более продвинутые архитектуры нейронных сетей, которые предназначены для работы с последовательностями — convolutional neural networks, recurrent neural networks
  • Использовать не только цену закрытия, а все данные из нашего .csv (high, low, open, close, volume) — то есть в каждый момент времени обращать внимание на всю доступную информацию
  • Оптимизировать гиперпараметры — размер окна, количество нейронов в скрытых слоях, шаг обучения — все эти параметры были взяты несколько наугад, с помощью случайного поиска можно выяснить, что, возможно, нам надо смотреть на 45 дней назад и учить с меньшим шагом более глубокую сетку.
  • Использовать более подходящие для нашей задачи функции потерь (например, для прогнозирования изменения цены мы могли бы штрафовать нейронную за неправильный знак, обычная MSE к знаку числа инвариантна)

Занимаясь прогнозированием временных рядов, мы оставили без внимания главную цель — использовать эти данные для торговли и убедиться в том, что она будет прибыльная. Я бы хотел это показать в режиме вебинара онлайн и применить сверточные и рекуррентные сети для задачи прогнозирования плюс проверить прибыльность стратегий, использующих эти предсказания. Если кому-то интересно, жду в Hangouts on Air 5 мая в 18:00 по UTC.

Заключение

В этой статье мы применили самую простую архитектуру нейронных сетей для прогнозирования движения цен на рынке. Этот пайплайн можно использовать для любых временных рядов, главное — правильно выбрать предобработку данных, определить архитектуру сети, оценить качество работы алгоритма. В нашем случае у нас удалось с точностью 60% предсказывать тренд через 5 дней, используя окно цен в предыдущие 30 дней, что можно считать хорошим результатом. С количественным предсказанием изменения цены получился провал, для этой задачи целесообразно использовать более серьезные инструменты и статистический анализ временного ряда. Весь используемый код в IPython Notebook можно взять по ссылке.

Разрабатываем простую модель глубокого обучения для прогнозирования цен акций с помощью TensorFlow


Эксперт в области data science и руководитель компании STATWORX Себастьян Хайнц опубликовал на Medium руководство по созданию модели глубокого обучения для прогнозирования цен акций на бирже с использованием фреймворка TensorFlow. Мы подготовили адаптированную версию этого полезного материала.

Автор разместил итоговый Python-скрипт и сжатый датасет в своем репозитории на GitHub.

Импорт и подготовка данных


Хайнц экспортировал биржевые данных в csv-файл. Его датасет содержал n = 41266 минут данных, охватывающих торги 500 акциями в период с апреля по август 2017, также в него вошла информация по цене индекса S&P 500.

# Импорт данных
data = pd.read_csv('data_stocks.csv')
# Сброс переменной date
data = data.drop(['DATE'], 1)
# Размерность датасета
n = data.shape[0]
p = data.shape[1]
# Формирование данных в numpy-массив
data = data.values


Так выглядит временной ряд индекса S&P, построенный с помощью pyplot.plot(data['SP500']):

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

Подготовка данных для тестирования и обучения

Набор данных был разбит на два — одна часть для тестирования, а вторая для обучения. При этом, данные для обучения составили 80% от всего их объема и охватили период с апреля до приблизительно конца июля 2017 года, данные для тестирования оканчивались августом 2017 года.

# Данные для тестирования и обучения
train_start = 0
train_end = int(np.floor(0.8*n))
test_start = train_end
test_end = n
data_train = data[np.arange(train_start, train_end), :]
data_test = data[np.arange(test_start, test_end), :]

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

Масштабирование данных

Большинство архитектур нейронных сетей используют масштабирование входных данных (а иногда и выходных). Причина в том, что большинство функций активации нейронов вроде сигмовидной или гиперболической касательной (tanx) определены на интервалах [-1, 1] или [0, 1], соответственно. В настоящее время, наиболее часто используются активации выпрямленной линейной единицей (ReLU). Хайнц решил масштабировать входные данные и цели, использовав для этой цели MinMaxScaler в Python:

# Масштабирование данных
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(data_train)
data_train = scaler.transform(data_train)
data_test = scaler.transform(data_test)
# Построение X и y
X_train = data_train[:, 1:]
y_train = data_train[:, 0]
X_test = data_test[:, 1:]
y_test = data_test[:, 0]

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

Введение в TensorFlow

TensorFlow — отличный продукт, в настоящий момент это самый популярный фреймворк для решения задач машинного обучения и создания нейронных сетей. Бэкенд продукта основан на C++, однако для управления обычно используется Python (также существует замечательная библиотека TensorFlow для R). TensorFlow использует концепцию графического представления вычислительных задач. Такой подход позволяет пользователям определять математические операции в качестве элементов графов данных, переменных и операторов. Поскольку нейронные сети, по сути, и являются графами данных и математических операций, TensorFlow отлично подходит для работы с ними и машинного обучения. В примере ниже представлен граф, который решает задачу сложения двух чисел:

На рисунке выше представлены два числа, которые нужно сложить. Они хранятся в переменных a и b. Значения путешествуют по графу и попадают в узел, представленный квадратом, где и происходит сложение. Результат операции записывается в другую переменную c. Использованные переменные можно рассматривать как плейсхолдеры. Любые числа, попадающие в a и b, складываются, а результат записывается в c.

Именно так и работает TensorFlow — пользователь определяет абстрактное представление модели (нейронной сети) через плейсхолдеры и переменные. После этого первые наполняются реальными данными и происходят вычисления. Тестовый пример выше описывается следующим кодом в TensorFlow:

# Импорт TensorFlow
import tensorflow as tf

# Определение a и b в качестве плейсхолдеров
a = tf.placeholder(dtype=tf.int8)
b = tf.placeholder(dtype=tf.int8)

# Определение сложения
c = tf.add(a, b)

# Инициализация графа
graph = tf.Session()

# Запуск графа
graph.run(c, feed_dict={a: 5, b: 4})

После импорта библиотеки TensorFlow с помощью tf.placeholder() определяются два плейсхолдера. Они соответствуют двум голубым кругам в левой части изображения выше. После этого, с помощью tf.add() определяется операция сложения. Результат операции — это c = 9. При настроенных плейсхолдерах граф может быть исполнен при любых целочисленных значениях a и b. Понятно, что этот пример крайне прост, а нейронные сети в реальной жизни куда сложнее, но он позволяет понять принципы работы фреймворка.

Плейсхолдеры


Как сказано выше, все начинается с плейсхолдеров. Для того, чтобы реализовать модель, нужно два таких элемента: X содержит входные данные для сети (цены акций всех элементов S&P 500 в момент времени T = t) и выходные данные Y (значение индекса S&P 500 в момент времени T = t + 1).

Форма плейсхолдеров соответствует [None, n_stocks], где [None] означает, что входные данные представлены в виде двумерной матрицы, а выходные данные — одномерного вектора. Важно понимать, какая форма входных и выходных данных нужна нейросети и соответственным образом их организовать.

# Плейсхолдер
X = tf.placeholder(dtype=tf.float32, shape=[None, n_stocks])
Y = tf.placeholder(dtype=tf.float32, shape=[None])

Аргумент None означает, что в этой точке мы еще не знаем число наблюдений, которые пройдут через граф нейросети во время каждого запуска, поэтому он остается гибким. Позднее будет определена переменная batch_size, которая контролирует количество наблюдений в ходе обучающего «прогона».

Переменные

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

Модель состоит из четырех скрытых уровней. Первый содержит 1024 нейрона, что чуть более чем в два раза превышает объем входных данных. Последующие скрытые уровни всегда в два раза меньше предыдущего — они объединяют 512, 256 и 128 нейронов. Снижение числа нейронов на каждом уровне сжимает информацию, которую сеть обработала на предыдущих уровнях. Существуют и другие архитектуры и конфигурации нейронов, но в этом руководстве используется именно такая модель:

# Параметры архитектуры модели
n_stocks = 500
n_neurons_1 = 1024
n_neurons_2 = 512
n_neurons_3 = 256
n_neurons_4 = 128
n_target = 1
# Уровень 1: Переменные для скрытых весов и смещений
W_hidden_1 = tf.Variable(weight_initializer([n_stocks, n_neurons_1]))
bias_hidden_1 = tf.Variable(bias_initializer([n_neurons_1]))
# Уровень 2: Переменные для скрытых весов и смещений
W_hidden_2 = tf.Variable(weight_initializer([n_neurons_1, n_neurons_2]))
bias_hidden_2 = tf.Variable(bias_initializer([n_neurons_2]))
# Уровень 3: Переменные для скрытых весов и смещений
W_hidden_3 = tf.Variable(weight_initializer([n_neurons_2, n_neurons_3]))
bias_hidden_3 = tf.Variable(bias_initializer([n_neurons_3]))
# Уровень 4: Переменные для скрытых весов и смещений
W_hidden_4 = tf.Variable(weight_initializer([n_neurons_3, n_neurons_4]))
bias_hidden_4 = tf.Variable(bias_initializer([n_neurons_4]))

# Уровень выходных данных: Переменные для скрытых весов и смещений
W_out = tf.Variable(weight_initializer([n_neurons_4, n_target]))
bias_out = tf.Variable(bias_initializer([n_target]))

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

Разработка архитектуры сети

После определения требуемых весов и смещений переменных, сетевой топологии, необходимо определить архитектуру сети. Таким образом, плейсхолдеры (данные) и переменные (веса и смещения) нужно объединить в систему последовательных матричных умножений. Скрытые уровни сети трансформируются функциями активации. Эти функции — важные элементы сетевой инфраструктуры, поскольку они привносят в систему нелинейность. Существуют десятки функций активации, и одна из самых распространенных — выпрямленная линейная единица (rectified linear unit, ReLU). В данном руководстве используется именно она:

# Скрытый уровень
hidden_1 = tf.nn.relu(tf.add(tf.matmul(X, W_hidden_1), bias_hidden_1))
hidden_2 = tf.nn.relu(tf.add(tf.matmul(hidden_1, W_hidden_2), bias_hidden_2))
hidden_3 = tf.nn.relu(tf.add(tf.matmul(hidden_2, W_hidden_3), bias_hidden_3))
hidden_4 = tf.nn.relu(tf.add(tf.matmul(hidden_3, W_hidden_4), bias_hidden_4))

# Выходной уровень (должен быть транспонирован)
out = tf.transpose(tf.add(tf.matmul(hidden_4, W_out), bias_out))

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

Функция стоимости

Функция стоимости сети используется для генерации оценки отклонения между прогнозами сети и реальными результатами наблюдений в ходе обучения. Для решения проблем с регрессией используют функцию средней квадратичной ошибки (mean squared error, MSE). Данная функция вычисляет среднее квадратичное отклонение между предсказаниями и целями, но вообще для подсчета отклонения между может быть использована любая дифференцируемая функция.

# Функция стоимости
mse = tf.reduce_mean(tf.squared_difference(out, Y))

При этом, MSE отображает конкретные сущности, которые полезны для решения общей проблемы оптимизации.

Оптимизатор

Оптимизатор берет на себя необходимые вычисления, требующиеся для адаптации весов и переменных отклонений нейросети в ходе обучения. Эти вычисления ведут к подсчетам так называемых градиентов, которые обозначают направление необходимого изменения отклонений и весов для минимизации функции стоимости. Разработка стабильного и быстрого оптимизатора — одна из основных задач создателей нейронных сетей.

# Оптимизатор
opt = tf.train.AdamOptimizer().minimize(mse)

В данном случае используется один из наиболее распространенных оптимизаторов в сфере машинного обучения Adam Optimizer. Adam — это аббревиатура для фразы “Adaptive Moment Estimation” (адаптивная оценка моментов), он представляет собой нечто среднее между двумя другими популярными оптимизаторами AdaGrad и RMSProp

Инициализаторы

Инициализаторы используются для инициализации переменных перед стартом обучения. Поскольку нейронные сети обучаются с помощью численных техник оптимизации, начальная точки проблемы оптимизации — это один из важнейших факторов на пути поиска хорошего решения. В TensorFlow существуют различные инициализаторы, каждый из которых использует собственный подход. В данном руководстве использован tf.variance_scaling_initializer(), который реализует одну из стандартных стратегий инициализации.

# Инициализаторы
sigma = 1
weight_initializer = tf.variance_scaling_initializer(mode="fan_avg", distribution="uniform", scale=sigma)
bias_initializer = tf.zeros_initializer()

Примечание: в TensorFlow можно определять несколько функций инициализации для различных переменных внутри графа. Однако в большинстве случаев достаточно унифицированной инициализации.

Настройка нейросети

После определения плейсхолдеров, переменных, инициализаторов, функций стоимости и оптимизаторов, модель необходимо обучить. Обычно для этого используется подход мини-партий (minibatch training). В ходе такого обучения из набора данных для обучения отбираются случайные семплы данных размера n = batch_size и загружаются в нейросеть. Набор данных для обучения делится на n / batch_size кусков, которые затем последовательно отправляются в сеть. В этот момент в игру вступают плейсхолдеры X и Y. Они хранят входные и целевые данные и отправляют их в нейросеть.

Семплированные данные X проходят по сети до достижения выходного уровня. Затем TensorFlow сравнивает сгенерированные моделью прогнозы с реально наблюдаемыми целями Y в текущем «прогоне». После этого TensorFlow выполняет этап оптимизации и обновляет параметры сети, после обновления весов и отклонений, процесс повторяется снова для нового куска данных. Процедура повторяется до того момента, пока все «нарезанные» куски данных не будут отправлены в нейросеть. Полный цикл такой обработки называется «эпохой».

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

# Создание сессии
net = tf.Session()
# Запуск инициализатора
net.run(tf.global_variables_initializer())

# Настройка интерактивного графика 
plt.ion()
fig = plt.figure()
ax1 = fig.add_subplot(111)
line1, = ax1.plot(y_test)
line2, = ax1.plot(y_test*0.5)
plt.show()

# Количество эпох и размер куска данных
epochs = 10
batch_size = 256

for e in range(epochs):

    # Перемешивание данных для обучения
    shuffle_indices = np.random.permutation(np.arange(len(y_train)))
    X_train = X_train[shuffle_indices]
    y_train = y_train[shuffle_indices]

    # Обучение мини-партией
    for i in range(0, len(y_train) // batch_size):
        start = i * batch_size
        batch_x = X_train[start:start + batch_size]
        batch_y = y_train[start:start + batch_size]
        # Run optimizer with batch
        net.run(opt, feed_dict={X: batch_x, Y: batch_y})

        # Показать прогресс
        if np.mod(i, 5) == 0:
            # Prediction
            pred = net.run(out, feed_dict={X: X_test})
            line2.set_ydata(pred)
            plt.title('Epoch ' + str(e) + ', Batch ' + str(i))
            file_name = 'img/epoch_' + str(e) + '_batch_' + str(i) + '.jpg'
            plt.savefig(file_name)
            plt.pause(0.01)
# Вывести финальную фукнцию MSE после обучения
mse_final = net.run(mse, feed_dict={X: X_test, Y: y_test})
print(mse_final)

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

Как видно, нейросеть быстро адаптируется к базовой форме временного ряда и продолжает искать наилучшие паттерны данных. После прошествия 10 эпох мы получаем результаты, очень близкие к тестовым данным. Финальное значение функции MSE составляет 0,00078 (очень маленькое значение из-за того, что цели масштабированы). Средняя абсолютная процентная погрешность прогноза на тестовом наборе равняется 5,31% — очень хороший результат. Важно понимать, что это лишь совпадение с тестовыми, а не реальными данными.

График рассеяния между предсказанными и реальными ценами S&P

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

Другие материалы по теме финансов и фондового рынка от ITI Capital:

Машинное обучение для прогнозирования тенниса: часть 2 / Habr


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

Содержание
Часть 2
Машинное обучение в теннисе
Модели машинного обучения

Проблемы с машинным обучением

Кейсы МО для прогнозирования тенниса

Машинное обучение в теннисе

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

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

С точки зрения существующих алгоритмов, прогнозирование тенниса можно рассмотреть с двух сторон:

  1. Как задачу регрессии, в которой выходное значение является вещественной величиной. Выход может представлять вероятность выигрыша матча напрямую, однако истинные вероятности выигрыша прошлых матчей неизвестны, что вынуждает нас использовать дискретные значения для меток обучающих примеров (например, 1 для победы, 0 для поражения). Иначе, можно прогнозировать вероятности выигрыша очка при подаче и вставлять их в иерархические выражения Барнета и О’Майли для нахождения вероятности выигрыша матча, но это возвращает нас к марковским цепям.
  2. Как задачу бинарной классификации, в которой можно попытаться классифицировать матчи по категориям «победа» или «поражение». Некоторые алгоритмы классификации также дают некоторую степень точности события, принадлежащего к классу, что можно использовать как вероятность победы в матче.

Модели машинного обучения

Логистическая регрессия

Несмотря на свое название, логистическая регрессия это по сути алгоритм классификации. Главными в алгоритме являются свойства логистической функции. Логистическая функция σ(t) определяется как:

Как видно на рисунке ниже, логистическая функция отображает вещественные входные значения в диапазоне от –∞ до +∞ и от 0 до 1, позволяя интерпретировать выходы как вероятности.

Логистическая функция σ(t)

Модель логистической регрессии для прогнозирования матчей состоит из вектора n признаков матча x = (x1, x2, …, xn) и вектора n+1 вещественных параметров модели β = (β0, β1, …, βn). Для прогнозирования с помощью модели сначала проецируем точку в нашем n-размерном пространстве признаков на вещественное число:

Теперь можно преобразовать z в значение в приемлемом диапазоне вероятностей (от 0 до 1) с помощью логистической функции, определенной выше:

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


где N – количество матчей в выборке
pi – вероятность прогноза победы для матча i
yi– реальный исход матча i (0 – поражение, 1 — победа)

Рисунок ниже показывает логистические потери, возникающие из-за одного матча для различных прогнозируемых вероятностей, при условии, что матч завершился победой предсказанного игрока. Любое отклонение от самого точного предсказания p = 1,0 штрафуется.

Логистические потери при верном прогнозе матча

В зависимости от величины выборки выбирается один из двух методов обучения (т.е. минимизации логистических потерь):

1. стохастическое градиентное убывание – медленные итеративный метод, подходит для больших выборок;

2. максимальное правдоподобие – более быстрая численная аппроксимация, не подходит для больших выборок.

Большинство опубликованных моделей машинного обучения используют логистическую регрессию. Clarke and Dyte [8] применяют модель логистической регрессии к разнице по очкам двух игроков в рейтинге ATP для прогнозирования исхода сета. Иными словами они используют одноразмерное пространство признаков x = (rankdiff) и оптимизируют β1, так чтобы функция σ(β1 * rankdiff) давала наилучшее предсказание для обучающей выборки. Параметр β0 опущен в модели, так как rankdiff 0 даст вероятность победы в матче 0,5. Вместо непосредственного прогнозирования исхода матча Кларк и Дайт предсказывают вероятность победы в сете и моделируют вероятность победы в матче, таким образом увеличивая размер выборки. Модель использовалась для прогнозирования результатов нескольких мужских турниров в 1998 и 1999 гг., однако авторы не приводят данных о точности предсказания, упоминая только, что результаты удовлетворительные.

Ma, Liu and Tan [9] использовали большее пространство признаков из 16 переменных, принадлежащих к трем категориям: навыки и результативность игрока, физические параметры игрока, параметры матча. Модель обучалась на матчах с 1991 по 2008 гг. и использовалась для выдачи рекомендаций игрокам: например, «больше тренировать прием подачи».

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

Нейронные сети

Искусственная нейронная сеть – это система взаимосвязанных нейронов, созданная по модели биологических нейронов. Каждый нейрон вычисляет значение из сигналов на входе, которое затем может быть передано на вход другим нейронам.
Нейронная сеть прямого распространения (то есть сеть с механизмом прогнозирования событий, feed-forward network) – это ориентированный ациклический граф. Как правило, нейросети имеют несколько слоев, при этом каждый нейрон в невходном слое связан со всеми нейронами в предыдущем слое. На рисунке ниже показана трехслойная нейронная сеть.

Трехслойная нейронная сеть прямого распространения

Каждой связи в сети присваиваются веса. Нейрон использует входной сигнал и его вес для вычисления значения на выходе. Типичным методом компоновки сети является нелинейная взвешенная сумма:


где wi – вес входных данных xi.

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

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

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

Somboonphokkaphan [10] обучил трехслойную нейросеть для прогнозирования теннисных матчей с использованием алгоритма обратного распространения. Автор исследовал и сравнил несколько разных сетей с разными наборами входных параметров. Лучшая нейронная сеть состоит из 27 входных узлов, представляющих такие признаки матча и игрока как поверхность корта, процент выигрыша на первой подаче, второй подаче, ответной подаче, брейк-пойнтах и т.д. Автор утверждает о точности около 75% при прогнозировании исходов матчей турниров Большого шлема в 2007 и 2008 годов.

Sipko [11] использует логистическую регрессию и нейронные сети, проверяя модели на выборке из 6135 матчей турниров ATP 2013-2014 гг., ROI наиболее точной модели составил 4,35%, что по заявлению автора на 75% лучше современных стохастических моделей.

После публикации первой части статьи SpanishBoy нашел на GitHub реализацию моделей Сипко: их результат – 65%, однако ROI получился отрицательным.

Метод опорных векторов

Машины опорных векторов (support vector machines, SVM), как и другие описанные здесь алгоритмы машинного обучения, это алгоритм обучения с учителем. Он был предложен Владимиром Вапником и Алексеем Червоненкисом в 1963 г. и является одним из наиболее популярных современных методов обучения по прецедентам.

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

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

Выпускники MIT Wagner and Narayanan [12] опубликовали курсовую работу, где они использовали SVM для прогнозирования победителей в интерактивной игре ATP World Tour Draw Challenge, проводившейся ассоциацией теннисистов-профессионалов до 2014 г. Суть игры — перед началом мирового турнира ATP любой желающий на сайте ATP пытался по турнирной таблице предсказать победителей во всех предстоящих матчах вплоть до победителя турнира. Авторы использовали 15 признаков, в основном посетовую статистику игроков. Обучающая выборка составила 40000 примеров, для тестирования модели использовали перекрестную проверку на 6000 примерах. Максимальная точность модели составила 65%.

Работа Panjan et al. [13] не касается напрямую прогнозирования исходов матчей. Они применяли SVM, наряду с другими алгоритмами классификации, для прогнозирования успешности карьеры молодых теннисистов из Словении в сравнении с их сверстниками и старшими теннисистами.

Другие алгоритмы МО

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

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

Проблемы с машинным обучением

Переобучение

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

Оптимизация гиперпараметров

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

Live-прогнозирование

Эксперт по ставкам на теннис Питер Уэбб утверждает, что более 80% всех ставок на теннис размещаются непосредственно во время матча. Стохастические модели могут прогнозировать вероятность исхода матча с любого начального счета, а значит, их можно использовать для live-ставок. Модели машинного обучения как правило не перестраиваются по ходу текущего матча. И хотя текущий счет можно было бы использовать в качестве признака матча, ресурсоемкость такой модели выросла бы в разы, а влияние на точность или ROI могло быть минимальным.

Женский теннис

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

Кейсы МО для прогнозирования тенниса

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

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

Одна группа сервисов предоставляет вероятности победы обоих игроков в матче, оставляя статистику матча и историю игрока для самостоятельного анализа пользователя. Таким образом, они используют результаты прогнозирования на основе стохастических иерархических методов. Таких ресурсов большинство: toptennistips.com, robobet.info и т. д.

Сервисы на основе машинного обучения анализируют не только вероятности выигрыша, но и применяют самообучающиеся алгоритмы к исторической статистике по игрокам и параметрам матча. Такие системы создали IBM, Microsoft и российский сервис OhMyBet!

IBM

Система от IBM Keys to the Match для прогнозирования тенниса продвигается компанией с 2013 года как предиктивный аналитический инструмент для четырех турниров Большого шлема: Уимблдона и Открытых чемпионатов Австралии, Франции и США. Для каждого игрока система анализирует его уникальный стиль игры и дает рекомендации по трем ключевым показателям (keys), которых должен достигнуть теннисист, чтобы увеличить свои шансы на выигрыш в текущем матче. «Ключи» публикуюся на официальных сайтах турниров.

Система берет статистику турниров Большого шлема с 2005 г., это почти 12 000 матчей. IBM уже много лет является официальным партнером турниров Большого шлема: компания собирает и обрабатывает всю статистику этих матчей. IBM утверждает, что для каждого матча Keys to the Match анализирует до 41 миллиона точек данных, в том числе очки, счет, длительность, скорость подачи, процент подач, количество ударов, типы ударов и т. д.

На основании анализа система определяет 45 ключевых динамических показателей игры и выделяет из них три, которые наиболее важны для каждого игрока в данном матче: 19 ключей для атаки, 9 для защиты, 9 для выносливости и 8 ключей, описывающих общий стиль игры. За турнир система создает в общей сложности 5500 предиктивных моделей.

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

IBM не раскрывает, какие именно прогностические алгоритмы используются в системе. Более того, несмотря на фразу «предиктивная аналитика», постоянно встречающуюся в маркетинговых материалах о Keys to the Match, представитель IBM Кеннет Дженсен подчеркивает: «Система не создана для прогнозирования победителя в матче или сете. Цель Keys to the Match – определить три показателя результативности игрока и отследить текущую игру теннисиста в сравнении с его предыдущими результатами и показателями сопоставимых игроков».

Microsoft

Система искусственного интеллекта Cortana Intelligence Suite от Microsoft пока не использовалась для прогнозирования тенниса, однако ее активно тестируют на прогнозировании футбольных матчей, поэтому рассказ о ней включен в этот обзор (более подробно можно почитать здесь).

Кортану впервые опробовали для прогнозирования спорта в 2014 г, когда она предсказывала результаты матчей Чемпионата мира по футболу. Тогда правильными оказались 15 из 16 прогнозов исходов игр. После этого Microsoft составляла прогнозы для чемпионата мира по футболу среди женщин, английской Премьер-лиги, Лиги чемпионов УЕФА, чемпионата Бразилии, чемпионата Франции, чемпионата Испании, чемпионата Германии, чемпионата Италии.

Для прогнозирования результатов система использует комплексный анализ двух факторов: статистические данные (соотношение побед и поражений команды, количество забитых голов, место проведения матча, погодные условия) и данные веб-поиска и социальных сетей (феномен «коллективного разума»). Шанс выигрыша каждой команды определяется в процентном соотношении, рассчитывается вероятность ничьей в матчах для каждой игры отборочного тура.

В целом феномен «коллективного знания» недооценен, считают в Microsoft. Результаты мероприятий, на которые, казалось бы, общественное мнение повлиять не может (футбольные чемпионаты как раз этот случай), на самом деле можно предсказать, анализируя поведение людей в интернете. Так Cortana Intelligence Suite прогнозирует результаты ТВ-шоу, выборов, церемоний награждения и самых разных конкурсов, основанных на голосовании. Система выявляет, какие именно публичные действия пользователей коррелируют с распределением голосов. На этих корреляциях и составляются предиктивные алгоритмы. Доказано, что в случаях, когда отдельно взятые эксперты могут ошибаться, анализ общественного мнения добавляет 5% к точности прогноза.

Однако, футбольный матч — это не голосование, а по своей структуре он сложнее тенниса, и результаты прогнозов Кортаны пока все еще далеки от идеала. Так, для Евро 2016 система прогнозировала, что с вероятностью 66% чемпионом станет Германия, а в матче с Англией 11 июня Россия не забьет ни одного гола, проведет менее четырех атак, а число результативных пасов не превысит 221.

Результат нам известен.

OhMyBet!

Сервис OhMyBet! создан выпускниками Физтеха и ВМиК МГУ. В начале июля заметка о сервисе появилась на vc.ru, где создатели кратко рассказали о системе. Изучение предиктивных алгоритмов в выпускных и диссертационных проектах привело авторов к мысли отработать свои модели на теннисных матчах.

Из данных о 825 000 сыгранных матчей в турнирах ITF и ATF с 2000 по 2014 выделили такие признаки как результат матча, покрытие, турнир, количество эйсов, количество двойных ошибок, процент выигрыша на первой и второй подаче, средняя скорость подачи каждого игрока, возраст игроков, оценочная мотивация выигрыша, предыдущие встречи игроков, травмы, время отдыха между матчами и т. д. К этим данным применили алгоритмы машинного обучения.

Валидация модели проводилась на матчах 2015 года. Результат: 12% ROI за 2015 год, при этом точность системы составила 75-77%. Максимальная точность в 2015 году – 85%, однако ROI при этом снижается.

Высокий ROI обеспечивается за счет того, что алгоритм сам отсекает прогнозы с низкими коэффициентами. Средний выигрышный коэффициент – 1,74. Всего с начала 2015 г по настоящий момент алгоритм дал 452 прогноза, 350 за 2015.

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

Последнее крупное обновление алгоритма было проведено в начале июля 2016 г., после этого был открыт полный доступ к сайту для пользователей. Статистика прогнозов с начала 2015 до текущего матча доступна на сайте в разделе История. С момента запуска авторы ведут открытый мониторинг прогнозов на платформе Blogabet, чтобы избежать обвинений в подтасовке статистики.

Библиография

8. S. R. Clarke and D. Dyte. Using official ratings to simulate major tennis tournaments. International Transactions in Operational Research, 7(6):585–594, 2000.
9. S. Ma, C. Liu, and Y. Tan. Winning matches in Grand Slam men’s singles: an analysis of player performance-related variables from 1991 to 2008. Journal of sports sciences, 31(11):1147–55, 2013.
10. A. Somboonphokkaphan, S. Phimoltares, and C. Lursinsap. Tennis Winner Prediction based on Time-Series History with Neural Modeling. IMECS 2009: International Multi-Conference of Engineers and Computer Scientists, Vols I and II, I:127–132, 2009.
11. M. Sipko. Machine Learning for the Prediction of Professional Tennis Matches. Technical report, Imperial College London, London, 2015.
12. A. Wagner, D. Narayanan. Using Machine Learning to predict tennis match outcomes. MIT 6.867 Final Project.
13. A. Panjan et al.: Prediction of the successfulness of tennis players with machine learning methods. Kinesiology 42(2010) 1:98-106

прогнозируем цены акций на фондовом рынке / Нетология corporate blog / Habr


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

Машинное и глубокое обучение стали новой эффективной стратегией, которую для увеличения доходов используют многие инвестиционные фонды. В статье я объясню, как нейронные сети помогают спрогнозировать ситуацию на фондовом рынке — например, цену на акции (или индекс). В основе текста мой проект, написанный на языке Python. Полный код и гайд по программе можно найти на GitHub. Другие статьи по теме читайте в блоге на Medium.

Нейронные сети в экономике

Изменения в сфере финансов происходят нелинейно, и иногда может показаться, что цены на акции формируются совершенно случайным образом. Традиционные методы временных рядов, такие как модели ARIMA и GARCH эффективны, когда ряд является стационарным — его основные свойства со временем не изменяются. А для этого требуется, чтобы ряд был предварительно обработан с помощью log returns или приведён к стационарности по-другому. Однако главная проблема возникает при реализации этих моделей в реальной торговой системе, так как при добавлении новых данных стационарность не гарантируется.

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

Обычно data science проект состоит из следующих операций:

  1. Сбор данных — обеспечивает набор необходимых свойств.
  2. Предварительная обработка данных — часто пугающий, но необходимый шаг перед использованием данных.
  3. Разработка и реализация модели — выбор типа нейронной сети и её параметров.
  4. Модели бэктестинга (тестирование на исторических данных) — ключевой шаг любой торговой стратегии.
  5. Оптимизация — поиск подходящих параметров.

Входные данные для нашей нейронной сети — данные о ценах на акции за последние 10 дней. С их помощью мы спрогнозируем цены на следующий день.

Сбор данных

К счастью, необходимые для этого проекта данные можно найти на Yahoo Finance. Данные можно собрать, используя их Python API pdr.get_yahoo_data(ticker, start_date, end_date) или напрямую с сайта.

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

В нашем случае данные нужно разбить на обучающие наборы, состоящие из 10-ти прошлых цен и цены следующего дня. Для этого я определил класс Preprocessing, который будет работать с обучающими и тестовыми данными. Внутри класса я определил метод get_train(self, seq_len), который преобразовывает обучающие входные и выходные данные в NumPy массивы, задавая определенную длину окна (в нашем случае 10). Весь код выглядит так:

def gen_train(self, seq_len):
   """
   Generates training data
   :param seq_len: length of window
   :return: X_train and Y_train
   """
   for i in range((len(self.stock_train)//seq_len)*seq_len - seq_len - 1):
       x = np.array(self.stock_train.iloc[i: i + seq_len, 1])
       y = np.array([self.stock_train.iloc[i + seq_len + 1, 1]], np.float64)
       self.input_train.append(x)
       self.output_train.append(y)
   self.X_train = np.array(self.input_train)
   self.Y_train = np.array(self.output_train)

Аналогично я определил метод, который преобразовывает тестовые данные X_test и Y_test.

Модели нейронных сетей

Для проекта я использовал две модели нейронных сетей: Многослойный перцептрон Румельхарта (Multilayer Perceptron — MLP) и модель Долгой краткосрочной памяти (Long Short Term Model — LSTM). Кратко расскажу о том, как работают эти модели. Подробнее о MLP читайте в другой статье, а о работе LSTM — в материале Джейкоба Аунгиерса.

MLP — самая простая форма нейронных сетей. Входные данные попадают в модель и с помощью определённых весов значения передаются через скрытые слои для получения выходных данных. Обучение алгоритма происходит от обратного распространения через скрытые слои, чтобы изменить значение весов каждого нейрона. Проблема этой модели — недостаток «памяти». Невозможно определить, какими были предыдущие данные и как они могут и должны повлиять на новые. В контексте нашей модели различия за 10 дней между данными двух датасетов могут иметь значение, но MLP не способны анализировать такие связи.

Для этого используется LSTM или Рекуррентные нейронные сети (Recurrent Neural Networks — RNN). RNN сохраняют определенную информацию о данных для последующего использования, это помогает нейронной сети анализировать сложную структуру связей между данными о ценах на акции. Но с RNN возникает проблема исчезающего градиента. Градиент уменьшается, потому что количество слоев повышается и уровень обучения (значение меньше единицы) умножается в несколько раз. Решают эту проблему LSTM, увеличивая эффективность.

Реализация модели

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

Важный этап работы с ценами на акции — нормализация данных. Обычно для этого вы вычитаете среднюю погрешность и делите на стандартную погрешность. Но нам нужно, чтобы эту систему можно было использовать в реальной торговле в течение определенного периода времени. Таким образом, использование статистики может быть не самым точным способом нормализации данных. Поэтому я просто разделил все данные на 200 (произвольное число, по сравнению с которым все другие числа малы). И хотя кажется, что такая нормализация ничем не обоснована и не имеет смысла, она эффективна, чтобы убедиться, что веса в нейронной сети не становятся слишком большими.

Начнем с более простой модели — MLP. В Keras строится последовательность и поверх неё добавляются плотные слои. Полный код выглядит так:

model = tf.keras.models.Sequential()

model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(100, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))

model.compile(optimizer="adam", loss="mean_squared_error")

С помощью Keras в пяти строках кода мы создали MLP со скрытыми слоями, по сто нейронов в каждом. А теперь немного об оптимизаторе. Популярность набирает метод Adam (adaptive moment estimation) — более эффективный оптимизационный алгоритм по сравнению с стохастическим градиентным спуском. Есть два других расширения стохастического градиентного спуска — на их фоне сразу видны преимущества Adam:

AdaGrad — поддерживает установленную скорость обучения, которая улучшает результаты при расхождении градиентов (например, при проблемах с естественным языком и компьютерным зрением).

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

Adam объединяет в себе преимущества этих расширений, поэтому я выбрал его.

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

model.fit(X_train, Y_train, epochs=100)

Когда модель готова, нужно проверить её на тестовых данных, чтобы определить, насколько хорошо она сработала. Это делается так:

model.evaluate(X_test, Y_test)

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

Для модели LSTM используется похожая процедура, поэтому я покажу код и немного объясню его:

model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(20, input_shape=(10, 1), return_sequences=True))
model.add(tf.keras.layers.LSTM(20))
model.add(tf.keras.layers.Dense(1, activation=tf.nn.relu))

model.compile(optimizer="adam", loss="mean_squared_error")

model.fit(X_train, Y_train, epochs=50)

model.evaluate(X_test, Y_test)

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

Модели бэктестинга

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

def back_test(strategy, seq_len, ticker, start_date, end_date, dim):
   """
   A simple back test for a given date period
   :param strategy: the chosen strategy. Note to have already formed the model, and fitted with training data.
   :param seq_len: length of the days used for prediction
   :param ticker: company ticker
   :param start_date: starting date
   :type start_date: "YYYY-mm-dd"
   :param end_date: ending date
   :type end_date: "YYYY-mm-dd"
   :param dim: dimension required for strategy: 3dim for LSTM and 2dim for MLP
   :type dim: tuple
   :return: Percentage errors array that gives the errors for every test in the given date range
   """
   data = pdr.get_data_yahoo(ticker, start_date, end_date)
   stock_data = data["Adj Close"]
   errors = []
   for i in range((len(stock_data)//10)*10 - seq_len - 1):
       x = np.array(stock_data.iloc[i: i + seq_len, 1]).reshape(dim) / 200
       y = np.array(stock_data.iloc[i + seq_len + 1, 1]) / 200
       predict = strategy.predict(x)
       while predict == 0:
           predict = strategy.predict(x)
       error = (predict - y) / 100
       errors.append(error)
       total_error = np.array(errors)
   print(f"Average error = {total_error.mean()}")

Однако, это упрощенная версия тестирования. Для полной системы бэктестинга нужно учитывать такие факторы, как «ошибка выжившего» (survivorship bias), тенденциозность (look ahead bias), изменение ситуации на рынке и транзакционные издержки. Так как это только образовательный проект, хватает и простого бэктестинга.
Прогноз моей модели LSTM на цены акций Apple в феврале

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

Оптимизация гиперпараметров

Для улучшения результатов модели после тестирования часто нужна оптимизация. Я не включил её в версию с открытым исходным кодом, чтобы читатели могли сами попробовать оптимизировать модель. Тем, кто не умеет оптимизировать, придется найти гиперпараметры, которые улучшат производительность модели. Есть несколько методов поиска гиперпараметров: от подбора параметров по сетке до стохастических методов.

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

Вывод

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

От редакции

Курсы «Нетологии» по теме:

Прогнозирование финансовых временных рядов / Habr


Введение

Всем привет, раз на хабре пошел цикл статей про нейронные сети, то и я напишу про возможность использования нейронных сетей в задаче прогнозирования финансовых временных рядов.
Существует несколько различных теорий о возможности прогнозирования фондовых рынков. Одна из них — гипотеза эффективного рынка, согласно ей, в цене акции уже учтена вся имеющиеся информация и делать прогнозы бессмысленно. Продолжением этой гипотезы можно назвать теорию случайных блужданий.
В теории случайных блужданий информация подразделяется на две категории — предсказуемую, известную и новую, неожиданную. Если предсказуемая, а тем более уже известная информация уже заложена в рыночные цены, то новая неожиданная информация в цене пока еще не присутствует. Одним из свойств непредсказуемой информации является ее случайность и, соответственно, случайность последующего изменения цены. Гипотеза эффективного рынка объясняет изменение цен поступлениями новой неожиданной информации, а теория случайных блужданий дополняет это мнением о случайности изменения цен.

Краткий практический вывод теории случайных блужданий — игрокам рекомендуется использовать в своей работе стратегию «покупай и держи». Следует заметить, что расцвет теории случайных блужданий пришелся на 70-е годы, когда на фондовом рынке США, традиционно являющемся главным полигоном проверки и использования всех новых экономических теорий, не было явных тенденций, а сам рынок находился в узком коридоре. Согласно гипотезе эффективного рынка и теории случайных блужданий прогнозирование цен невозможно. [1]
Однако, большинство участников рынка все же использует различные методы для прогнозирования, предполагая, что сам ряд полон скрытых закономерностей.
Такие скрытые эмпирические закономерности пытался выявить в 30-х годах в серии своих статей основатель технического анализа Эллиот (R.Elliott).
В 80-х годах неожиданную поддержку эта точка зрения нашла в незадолго до этого появившейся теории динамического хаоса. Эта теория построена на противопоставлении хаотичности и стохастичности (случайности). Хаотические ряды только выглядят случайными, но, как детерминированный динамический процесс, вполне допускают краткосрочное прогнозирование. Область возможных предсказаний ограничена по времени горизонтом прогнозирования, но этого может оказаться достаточно для получения реального дохода от предсказаний (Chorafas, 1994). И тот, кто обладает лучшими математическими методами извлечения закономерностей из зашумленных хаотических рядов, может надеяться на большую норму прибыли — за счет своих менее оснащенных собратьев. [2]

Методы прогнозирования

В настоящее время профессиональные участники рынка используют различные методы прогнозирования финансовых временных рядов, основные из них:
1) экспертные методы прогнозирования.
Самый распространенный метод из группы экспертных методов — метод Дельфи. Суть метода заключается в сборе мнений различных экспертов и их обобщение в единую оценку. Если мы прогнозируем этим методом финансовые рынки, то нам нужно выделить экспертную группу людей разбирающихся в этой предметной области (это могут быть аналитики, профессиональные трейдеры, инвесторы, банки итд), провести анкетирование или опрос и сделать обобщение о текущей ситуации на рынке.
2) Методы логического моделирования.
Основаны на поиске и выявлении закономерностей рынка в долгосрочной перспективе.
Сюда входят методы:
— метод сценариев («если — то»), описание последовательностей исходов из того или иного события, с созданием базы знаний;
— методы прогнозов по образу;
— метод аналогий.
3) Экономико-математические методы.
Методы из этой группы базируются на создании моделей исследуемого объекта. Экономико-математическая модель — это определенная схема, путь развития рынка ценных бумаг при заданных условиях. При прогнозировании финансовых временных рядов используют статистические, динамические, микро- макро-, линейные, нелинейные, глобальные, локальные, отраслевые, оптимизационные, дескриптивные. Очень значимы для финансовых наук оптимизационные модели, они представляют из себя систему уравнений, куда входят различные ограничения, а также особое уравнение называемое функционалом оптимальности (или критерием оптимальности). С помощью него находят оптимальное, наилучшее решение по какому-либо показателю.
4) Статистические методы.
Статистические методы прогнозирования применительно, для финансовых временных рядов основаны на построении различных индексов (диффузный, смешанный), расчет значений дисперсии, мат ожидания, вариации, ковариации, интерполяции, экстраполяции.
5) Технический анализ.
Прогнозирование изменений цен в будущем на основе анализа изменений цен в прошлом. В его основе лежит анализ временны́х рядов цен — «чартов» (от англ. chart). Помимо ценовых рядов, в техническом анализе используется информация об объёмах торгов и другие статистические данные. Наиболее часто методы технического анализа используются для анализа цен, изменяющихся свободно, например, на биржах. В техническом анализе множество инструментов и методов, но все они основаны на одном предположении: из анализа временны́х рядов, выделяя тренды, можно спрогнозировать поведение цен.
6) Фундаментальный анализ.
Метод прогнозирования рыночной (биржевой) стоимости компании, основанных на анализе финансовых и производственных показателей её деятельности.
Фундаментальный анализ используется инвесторами для оценки стоимости компании (или её акций), которая отражает состояние дел в компании, рентабельность её деятельности. При этом анализу подвергаются финансовые показатели компании: выручка, EBITDA (Earnings Before Interests Tax, Deprecation and Amortization), чистая прибыль, чистая стоимость компании, обязательства, денежный поток, величина выплачиваемых дивидендов и производственные показатели компании.
[3] [4] [5]

Использование нейронных сетей для прогнозирование финансовых временных рядов

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

Рис. 1 — Интервальный график в виде японских свечей индекса РТС. Период — день.

Для справки: каждая фигура на графике показывает нам определенный промежуток времени (в данном случае один день) и движения цены за этот промежуток. Опишем их:

— цена открытия — это величина цены в начале этого промежутка времени

— цена закрытия — это величина цены в конце этого промежутка времени

— максимальная цена — это максимальная цена за весь этот промежуток времени

— минимальная цена — это минимальная цена за весь этот промежуток времени

— если цена шла вверх (бычий тренд) за этот период — тело свечи будет белым (или прозрачным)

— если цена шла вниз (медвежий тренд) за этот период — тело свечи будет черным (или закрашенным) [6]


Рис. 2 — Японские свечи.

Действительно значимыми для предсказаний являются изменения котировок. Поэтому на вход нейронной сети после предварительной обработки будем подавать ряд процентных приращений котировок, рассчитанных по формуле X[t] / X[t-1], где X[t] и X[t-1] цены закрытия периодов.


Рис. 3 — Ряд процентных приращений котировок, рассчитанных по формуле X[t] / X[t-1].

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


Рис. 4 — Распределение процентных приращений котировок.

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


Рис. 5 — Границы 6 отрезков, количество процентных приращений в каждом отрезке равно.

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


Рис. 6 — Перекодирование процентных приращений.

И получим равномерное распределение.


Рис. 7 — Равномерное распределение.

Задача получения входных образов для формирования обучающего множества в задачах прогнозирования временных рядов предполагает использование метода «окна». Этот метод подразумевает использование «окна» с фиксированным размером, способного перемещаться по временной последовательности исторических данных, начиная с первого элемента, и предназначены для доступа к данным временного ряда, причем «окно» размером N, получив такие данные, передает на вход нейронной сети элементы с 1 по N-1, а N-ый элемент используется в качестве выхода.


Рис. 8 — Метод «окна».

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

1) количество элементов обучающей выборки — чем больше элементов, тем больше противоречивость и повторяемость;

2) количество классов на которые перекодировали процентные приращения — при увеличение снижается противоречивость и повторяемость;

3) глубина погружения в финансовый временной ряд («окно») — чем больше глубина, тем меньше противоречивость и меньше повторяемость.

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

Для практического примера спрогнозируем направления приращений индекса РТС с 16.01.2012 по 17.04.2012 гг, период — день.


Рис. 9 — График индекса РТС с 8.01.2012 по 18.04.2012 гг, период — день.

Создадим коллекцию нейронных сетей, показавших наилучшие результаты (более 70% правильно спрогнозированных направлений изменений значения индекса) на тестовом множестве (последние 50 периодов). Через каждые 5 периодов коллекция пересоздается, в тестовое множество включается уже прогнозированные периоды. Нейронные сети, входящие в коллекцию не однотипны — у каждой подбирается размер обучающей выборки, количество классов на которые перекодируются процентные приращения, глубина погружения («окно») и количество нейронов в скрытом слое так, чтобы наиболее точно прогнозировала текущую рыночную ситуацию (последние 50 периодов).

Базовая архитектура используемых нейронных сетей — многослойный перцептрон с одним скрытым слоем. Есть прекрасная готовая реализация в библиотеке ALGLIB [7]. В качестве алгоритма обучения используем L-BFGS алгоритм (limited memory BFGS), квази-Ньютоновский метод с трудоемкостью итерации, линейной по количеству весовых коэффициентов WCount и размеру обучающего множества, и умеренными требованиями к дополнительной памяти — O(WCount).

Пример коллекции:

Прогноз с: 16.01.2012 по: 20.01.2012

Количество сетей: 16

Параметры сетей:

Вход: 3 Скрытый слой: 18 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 74,6 Результат на тестовой выб.: 72,5

Вход: 3 Скрытый слой: 19 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 74,6 Результат на тестовой выб.: 72,5

Вход: 3 Скрытый слой: 20 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 74,6 Результат на тестовой выб.: 72,5

Вход: 4 Скрытый слой: 18 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 75,6 Результат на тестовой выб.: 74,5

Вход: 4 Скрытый слой: 20 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 74,1 Результат на тестовой выб.: 72,5

Вход: 5 Скрытый слой: 19 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 74,6 Результат на тестовой выб.: 70,6

Вход: 5 Скрытый слой: 20 Количество классов: 4 Длина обучающей выборки: 200 Результат на об. выб.: 76,1 Результат на тестовой выб.: 72,5

Вход: 4 Скрытый слой: 18 Количество классов: 5 Длина обучающей выборки: 200 Результат на об. выб.: 67,2 Результат на тестовой выб.: 74,5

Вход: 5 Скрытый слой: 18 Количество классов: 5 Длина обучающей выборки: 200 Результат на об. выб.: 70,6 Результат на тестовой выб.: 74,5

Вход: 5 Скрытый слой: 19 Количество классов: 5 Длина обучающей выборки: 200 Результат на об. выб.: 76,6 Результат на тестовой выб.: 74,5

Вход: 5 Скрытый слой: 20 Количество классов: 5 Длина обучающей выборки: 200 Результат на об. выб.: 76,1 Результат на тестовой выб.: 74,5

Вход: 3 Скрытый слой: 18 Количество классов: 4 Длина обучающей выборки: 270 Результат на об. выб.: 74,9 Результат на тестовой выб.: 70,6

Вход: 3 Скрытый слой: 19 Количество классов: 4 Длина обучающей выборки: 270 Результат на об. выб.: 74,9 Результат на тестовой выб.: 70,6

Вход: 3 Скрытый слой: 20 Количество классов: 4 Длина обучающей выборки: 270 Результат на об. выб.: 74,9 Результат на тестовой выб.: 70,6

Вход: 5 Скрытый слой: 18 Количество классов: 4 Длина обучающей выборки: 340 Результат на об. выб.: 78,0 Результат на тестовой выб.: 70,6

Вход: 5 Скрытый слой: 19 Количество классов: 4 Длина обучающей выборки: 340 Результат на об. выб.: 79,5 Результат на тестовой выб.: 74,5

Параметры всех использованных коллекций можно посмотреть в файле

Так как прогнозируем направление изменения индекса РТС, то используем простейшую стратегию — открываем позицию по цене закрытия текущего периода и закрываем ее по цене закрытия прогнозируемого периода, фиксируя прибыль или убыток.


Рис. 10 — Результат работы.

Результат работы с 16.01.2012 по 17.04.2012 гг: 77% правильно прогнозированных направлений изменений значения индекса.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *