Наглядное сравнение известных моделей Prophet.

Модели пророков эффективны, интерпретируемы и просты в использовании. Но какой из них лучше?

В этом посте мы рассмотрим различия в реализации Prophet и Neural Prophet и проведем небольшой пример. Вот код.

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

Prophet (2017) является предшественником NeuralProphet (2020) — последний включает авторегрессивное глубокое обучение. Теоретически NeuralProphet всегда должен иметь равную или лучшую производительность, чем Prophet, поэтому сегодня мы проверим это утверждение.

Давайте углубимся.

Основные правила

Данные

Мы будем использовать ежедневные временные ряды энергопотребления Калифорнии (рис. 2).

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

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

Наконец, сделав еще одно наблюдение о данных, вы заметите, что имена осей — y и ds. Мы сохранили наши временные ряды в кадре данных pandas, который был реструктурирован в соответствии со спецификациями Prophet. Точный код, который был использован, следующий…

df = read_data() # helper func
df = df[['Local date','D']]
df.columns = ['ds','y']

Если хотите проследить, данные были скачаны из источника: Управление энергетической информации США (декабрь 2021 г.) и также доступны здесь. Вот информация об авторских правах.

Оценка

Нас будет интересовать метрика RMSE (рисунок 3).

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

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

В нашем случае мы начинаем наши итерации в 2017-12-22 и с шагом 180 дней заканчиваем около 2021-12-06.

Участник 1: Пророк

Наш первый конкурент — Facebook Prophet. Это алгоритм с открытым исходным кодом, который пользуется огромной популярностью с момента его создания в 2017 году. Его основные преимущества заключаются в том, что он прост в использовании, интерпретируется и легко взаимодействует с экспертом в предметной области.

С введениями в сторону, давайте приступим к кодированию.

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

m = Prophet()
m.fit(df)

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

# create forecast
future = m.make_future_dataframe(periods=365)
forecast = m.predict(future)
# create plots
pred_plot = plot_plotly(m, forecast)
comp_plot = plot_components_plotly(m, forecast)

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

Сначала у нас есть наш прогнозный график на рисунке 4.

Как видите, примерно в 2022 году наши данные прекращаются, и начинается наш прогноз, на что указывает отсутствие наблюдений (черные точки).

Хорошо, это красивая картинка, но она мало что говорит нам о том, что происходит за кулисами. Для этого обратимся к компонентному графику (рис. 5).

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

Разговор об интерпретируемой модели!

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

Но модель хороша настолько, насколько хороша ее точность, поэтому давайте посмотрим на точность.

Используя встроенные методы перекрестной проверки, RMSE для прогноза 365 составляет 48 810,12. Наше значение y исчисляется сотнями тысяч, где-то между 600 000 и 1,2 М, поэтому RMSE в 48 000 кажется довольно низким.

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

Конкурент 2: NeuralProphet

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

Займемся кодированием.

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

m = NeuralProphet()
metrics = m.fit(df, freq="D")

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

# create forecast
df_future = m.make_future_dataframe(df, periods=365)
forecast = m.predict(df_future)
# create plots
fig_forecast = m.plot(forecast)
fig_components = m.plot_components(forecast)
fig_model = m.plot_parameters()

Как и в приведенных выше значениях, давайте посмотрим на наш график прогноза (рис. 6).

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

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

Вердикт

Хорошо, теперь, когда у нас есть представление об обеих библиотеках, давайте проведем наш конкурс.

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

train_test_split_indices = list(range(365*2, len(df.index) - 365, 180))
train_test_splits = [(df.iloc[:i, :], df.iloc[i:(i+365), :]) 
                     for i in train_test_split_indices]

Отсюда мы можем перебрать train_test_splits, обучить обе модели и сравнить результаты.

После настройки данных мы готовы приступить к глубокому обучению в NeuralProphet…

neural_params =  dict(
    n_forecasts=365,
    n_lags=30,
    yearly_seasonality=True,
    weekly_seasonality=True,
    daily_seasonality=True,
    batch_size=64,
    epochs=200,
    learning_rate=0.03
)

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

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

Результаты довольно удивительны.

При обучении в течение 730 дней NeuralProphet намного превосходит Prophet. Однако с данными обучения за 910 и 1090 дней NeuralProphet с небольшим отрывом превосходит Prophet. И, наконец, с данными обучения за 1270 дней или более, Prophet превосходит NeuralProphet по точности.

Здесь NeuralProphet лучше работает с небольшими наборами данных, но Prophet лучше работает с большим количеством обучающих данных.

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

Одно из возможных объяснений заключается в том, что при достаточном количестве обучающих данных Prophet более эффективен на очень цикличных данных. Если большая часть движения является синусоидальной из-за сезонности (что, по-видимому, имеет место), будет трудно улучшить модель, основанную на рядах Фурье.

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

Пророк против правительства

Наконец, мы собираемся закончить на забавной ноте.

Каждый день EIA публикует прогноз на сутки вперед. Мне было любопытно сравнить наши годовые модели, и я быстро рассчитал RMSE и MAPE для прогноза правительства. Значения составили 28432,85 и 0,0242 соответственно.

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

Крутым и легким продолжением было бы попытаться победить правительство, используя любую модель Пророка. Не должно быть слишком сложно, верно?

Спасибо за чтение! Я напишу еще 24 поста, посвященных академическим исследованиям в индустрии DS. В моем комментарии есть ссылки на основной источник этого поста и некоторые полезные ресурсы.