Amazon GluonTS: Deep Learning для временных рядов
В июне 2019 года компания Amazon выложила в открытый доступ замечательный инструмент — GluonTS, позволяющий максимально быстро и эффективно строить, оценивать и использовать модели временных рядов, основанные на глубоком обучении и вероятностном подходе.
До этого момента одним из самых известных релизов открытой библиотеки для работы с временными рядами был Facebook Prophet, выпущенный в феврале 2017 года. В отличие от GluonTS, Facebook использовал более простой метод — аддитивную нелинейную модель временного ряда. Эта модель давала вполне адекватные результаты при минимуме затраченных усилий, однако не очень хорошо справлялась с данными, где отсутствовала ярко выраженная сезонность.
Что внутри GluonTS?
Amazon пошёл дальше и использовал рекуррентные нейронные сети (в частности, LSTM), а также свёртки и механизмы внимания, обернув всё это в крайне удобную верхнеуровневую библиотеку. В частности, GluonTS содержит: — инструменты, необходимые для построения и обучения наиболее распространённых архитектур нейронных сетей, а также компоненты для моделирования и трансформации вероятностных распределений; — механизмы для загрузки и предварительной обработки данных, в том числе автоматической генерации признаков из временных рядов; — несколько готовых к использованию state-of-the-art прогнозных моделей; — инструменты для оценки и сравнения различных моделей.
Если не вдаваться в подробности, GluonTS позволяет быстро и практически из коробки получить качественную модель временного ряда, на выходе из которой вместо точечной оценки прогнозных значений мы получаем целое смоделированное вероятностное распределение. Таким образом, мы можем с лёгкостью оперировать доверительными интервалами прогноза и с любой удобной нам вероятностью получать диапазон наиболее вероятных будущих значений ряда.
Пример на реальных данных
В оригинальной статье авторы использовали временной ряд с ценами акций компании Amazon. Ярко выраженных паттернов, за исключением восходящих/нисходящих трендов в финансовых временных рядах обычно не бывает, поэтому прогнозы в статье выглядят больше как некоторый шум, колеблющийся вокруг спрогнозированной линии тренда.
Для нашего примера возьмём чуть более богатый на события временной ряд — исторические траты внутриигровой валюты, взятые из одной мобильной игры.
import pandas as pd import matplotlib.pyplot as plt df = pd.read_csv('currency.csv', index_col=0) df.index = pd.to_datetime(df.index) df[:100].plot(linewidth=2, figsize=(17, 7)) plt.grid(axis='x') plt.legend() plt.show()
Во временном ряду хорошо видна 30-дневная цикличность, связанная с определёнными внунтриигровыми событиями, а также ярко выраженная недельная сезонность — по выходным игроки больше тратят валюту, а по будням активность спадает.
Попробуем построить модель. GluonTS предоставляет верхнеуровневую абстрацию
from gluonts.dataset.common import ListDataset training_data = ListDataset( [{"start": df.index[0], "target": df.currency_spent[:"2017-08-01"]}], freq = "D" )
Посмотрим, в какой формат преобразовались данные:
training_data.list_data [Out:] [{'start': Timestamp('2017-05-01 00:00:00', freq='D'), 'target': array([1199436., 1045515., 586111., 856601., 793775., 606535., 1112763., 1121218., 813844., 903343., 863465., 639224., 1030389., 1132645., 1018672., 1726870., 1378430., 532950., 828238., 823948., 592549., 939337., 862611., 551557., 878375., 784535., 613603., 1054658., 1026401., 682284., 986644., 924769., 633489., 1044957., 1088685., 798582., 1139786., 1066560., 754706., 1199406., 1186341., 958210., 1564553., 1470865., 1201275., 2418723., 2123070., 978338., 1536623., 1420586., 966259., 1232735., 1090762., 763828., 1153383., 1074039., 733943., 1103070., 1123779., 752524., 1123866., 1051964., 756827., 1109486., 1059961., 691291., 985221., 932805., 641340., 1038572., 1037868., 732303., 962492., 875898., 1029902., 1917268., 1662445., 791812., 1061339., 968767., 685321., 1020324., 995864., 785353., 1192613., 1068292., 710820., 1048429., 991163., 701672., 1239717., 1261953., 857930.], dtype=float32), 'source': SourceContext(source='list_data', row=1)}]
Имея такой датасет, можно переходить к построению модели. Внутри библиотеки есть огромное количество всевозможных гиперпараметров, начиная от самой архитектуры модели, и заканчивая настройкой первичной подготовки признаков для моделирования.
В этой статье подробно разбирать настройку мы не будем, а вместо этого посмотрим, что может получиться, если воспользоваться решением из коробки.
В качестве модели возьмём рекомендованную архитектуру, основанную на глубокой авторегрессионной модели (DeepAR). Как и при создании датасета, нужно не забыть указать частоту данных, на которой предстоит тренироваться. Также зададим число эпох, равное 20, а горизонт прогноза (т. е. на сколько шагов вперед модель должна уметь прогнозировать) — равным 30 дням.
from gluonts.model.deepar import DeepAREstimator from gluonts.trainer import Trainer estimator = DeepAREstimator( freq="D", prediction_length=30, trainer=Trainer(epochs=20) ) predictor = estimator.train(training_data=training_data)
После непродолжительной тренировки модель готова и можно смотреть на прогноз. Снова создадим
from gluonts.dataset.util import to_pandas test_data = ListDataset( [{"start": df.index[0], "target": df.currency_spent[:"2017-08-01"]}], freq = "D" ) for test_entry, forecast in zip(test_data, predictor.predict(test_data)): to_pandas(test_entry).plot(linewidth=2, figsize=(15, 7), label="historical values") forecast.plot(color='g', prediction_intervals=[50.0, 90.0], label="forecast") plt.legend(loc='upper left') plt.grid(axis='x')
В результате мы получили очень правдоподобный прогноз, который учитывает и недельную сезонность и 30-дневную цикличность. Хорошо видно, что доверительные интервалы прогноза расширяются в момент пика, где исторические значения были наименее стабильными, и сужаются в обычные дни, где дисперсия исторических данных была не такой большой.
Вывод
GluonTS — очень удобный инструмент, который позволяет максимально быстро и на верхнем уровне получить вероятностную модель временного ряда, используя глубокое обучение «под капотом». Помимо хороших результатов, которые получаются прямо из коробки, GluonTS можно тонко настраивать под любые нужды.
Подробнее о настройке гиперпараметров и сравнении качества GluonTS с другими методами прогнозирования временных рядов вы сможете узнать на занятии «Анализ временных рядов» курса «Machine Learning».