При использовании одной модели прогнозирования с общими весами на наборе данных, состоящем из множества временных рядов, можно достичь создания так называемой глобальной модели. Она особенно полезна в случаях, когда один временной ряд может не отражать всю динамику временных рядов. Кроме того, глобальные модели обеспечивают лучшую обобщенность и экономию размера модели.
Однако в случаях, когда многие временные ряды имеют только некоторые общие черты поведения, более подходящей может быть модель глобально-локального типа. В такой модели используется одна модель с общими весами для захвата общих поведений по всем временным рядам, в то время как некоторые компоненты моделируются отдельно для каждого временного ряда.
В этом руководстве мы продемонстрируем пример глобального локального моделирования, отдельно моделируя компоненты тренда и сезонности для каждого временного ряда в наборе данных почасовых нагрузок региона ERCOT.
Сначала загружаем данные:
if "google.colab" in str(get_ipython()):
# Удаление предустановленных пакетов из Colab для избежания конфликтов
!pip uninstall -y torch notebook notebook_shim tensorflow tensorflow-datasets prophet torchaudio torchdata torchtext torchvision
!pip install git+https://github.com/ourownstory/neural_prophet.git # может занять некоторое время
#!pip install neuralprophet # намного быстрее, но может не иметь последних обновлений/исправлений ошибок
import pandas as pd
from neuralprophet import NeuralProphet, set_log_level
from neuralprophet import set_random_seed
import numpy as np
set_random_seed(10)
set_log_level("ERROR", "INFO")
Извлекаем названия регионов, которые позже будут использованы при создании модели.
regions = list(df_ercot)[1:]
Глобальные модели можно активировать, когда входные данные df функции имеют дополнительную колонку «ID», которая идентифицирует различные временные ряды (помимо типичной колонки «ds», содержащей временные метки, и колонки «y», содержащей наблюдаемые значения временного ряда). В нашем примере мы выбираем данные за трехлетний интервал (с 2004 по 2007 год).
df_global = pd.DataFrame()
for col in regions:
aux = df_ercot[["ds", col]].copy(deep=True) # выберите столбец, связанный с регионом
aux = aux.iloc[:26301, :].copy(deep=True) # выберите данные до строки 26301 (временные метки с 2004 по 2007 год)
aux = aux.rename(columns={col: "y"}) # переименуйте столбец данных в 'y', что совместимо с Neural Prophet
aux["ID"] = col
df_global = pd.concat((df_global, aux))
Мы изменим тенденцию для СЕВЕРА и сезонность для ПОБЕРЕЖЬЯ.
df_global["y"] = (
np.where(df_global["ID"] == "COAST", -df_global["y"], df_global["y"]) # если регион COAST, инвертируем значения столбца "y"
+ 2 * df_global.loc[df_global["ID"] == "COAST", "y"].mean() # добавляем удвоенное среднее значение столбца "y" для COAST
)
df_global["y"] = np.where(df_global["ID"] == "NORTH", df_global["y"] + 0.1 * df_global.index, df_global["y"]) # если регион NORTH, добавляем 0.1 * индекс строки к значениям столбца "y"
df_global.loc[df_global["ID"] == "NORTH"].plot() # визуализируем данные для региона NORTH
df_global.loc[df_global["ID"] == "COAST"].plot() # визуализируем данные для региона COAST
Глобальное моделирование
Примечание: Обучение временного ряда, содержащего только компоненты тренда и сезонности, может привести к плохим результатам. Приведенный пример используется только для демонстрации новой функциональности локального моделирования множества временных рядов.
m = NeuralProphet(
trend_global_local="global", # используем глобальную модель для тренда
season_global_local="global", # используем глобальную модель для сезонности
changepoints_range=0.8, # доля данных для поиска точек изменений
epochs=20, # количество эпох обучения
trend_reg=5, # коэффициент регуляризации для тренда
)
m.set_plotting_backend("plotly-static") # устанавливаем бэкенд для визуализации графиков
Когда входными данными для функции split_df является pd.DataFrame со столбцом ID, тренировочные и валидационные данные предоставляются в аналогичном формате. Для глобальных моделей входные данные обычно разделяются в соответствии с долей времени, охватывающей все временные ряды (по умолчанию, когда есть более одного ID и когда local_split=False). Если пользователь хочет разделить каждый временной ряд локально, параметр local_split должен быть установлен в значение True. В этом примере мы разделим наши данные на тренировочные и тестовые (с 33% долей тестовой выборки - 2 года на обучение и 1 год на тестирование).
df_train, df_test = m.split_df(df_global, valid_p=0.33, local_split=True) # разделяем данные на тренировочный и тестовый наборы
print(df_train.shape, df_test.shape) # выводим размеры тренировочного и тестового наборов
После создания объекта NeuralProphet, модель может быть создана путем вызова функции fit
metrics = m.fit(df_train, freq="H") # обучаем модель на тренировочных данных с частотой "H" (час)
Убедитесь, что вы предоставляете данные, идентифицированные с ключами, связанными с соответствующими временными рядами поездов. Таким образом, подходящие параметры нормализации данных используются в процедурах после подгонки (т.е.,predict, test).
future = m.make_future_dataframe(df_test, n_historic_predictions=True) # создаем будущие даты на основе тестовых данных
forecast = m.predict(future) # делаем прогноз на будущее
Мы сейчас построим прогнозируемые временные ряды и параметры для:
NORTH: С корректировкой тренда
COAST: С корректировкой сезонности
EAST: Без изменений к оригиналу
North
m.plot(forecast[forecast["ID"] == "NORTH"]) # визуализация прогноза для региона NORTH
m.plot_parameters(df_name="NORTH") # визуализация параметров модели для региона NORTH
South
m.plot(forecast[forecast["ID"] == "COAST"]) # визуализация прогноза для региона COAST
m.plot_parameters(df_name="COAST") # визуализация параметров модели для региона COAST
East
m.plot(forecast[forecast["ID"] == "EAST"]) # визуализация прогноза для региона EAST
m.plot_parameters(df_name="EAST") # визуализация параметров модели для региона EAST
Metrics
test_metrics_global = m.test(df_test) # оценка модели на тестовых данных
test_metrics_global
Мы повторим вышеописанный процесс, но для локального моделирования тренда и сезонности.
m = NeuralProphet(
trend_global_local="local", # локальный тренд
season_global_local="local", # локальная сезонность
changepoints_range=0.8, # доля периода, в котором могут находиться точки изменения
epochs=20, # количество эпох обучения
trend_reg=5, # параметр регуляризации для тренда
)
m.set_plotting_backend("plotly-static") # выбор бэкэнда для построения графиков
metrics = m.fit(df_train, freq="H") # обучение модели на обучающем наборе данных с частотой "H" (часы)
future = m.make_future_dataframe(df_test, n_historic_predictions=True) # создание фрейма данных для будущих предсказаний на основе тестового набора данных с учетом исторических предсказаний
forecast = m.predict(future) # предсказание на основе будущего фрейма данных
North
m.plot(forecast[forecast["ID"] == "NORTH"]) # построение графика прогноза для региона "NORTH"
m.plot_parameters(df_name="NORTH") # визуализация параметров модели для региона "NORTH"
Coast
m.plot(forecast[forecast["ID"] == "COAST"]) # визуализация прогноза для региона "COAST"
m.plot_parameters(df_name="COAST") # визуализация параметров модели для региона "COAST"
East
m.plot(forecast[forecast["ID"] == "EAST"]) # визуализация прогноза для региона "EAST"
m.plot_parameters(df_name="EAST") # визуализация параметров модели для региона "EAST"
Metric
test_metrics_local = m.test(df_test) # вычисление метрик качества модели на тестовом наборе данных
test_metrics_local # вывод результатов