При использовании одной модели прогнозирования с общими весами на наборе данных, состоящем из множества временных рядов, можно достичь создания так называемой глобальной модели. Она особенно полезна в случаях, когда один временной ряд может не отражать всю динамику временных рядов. Кроме того, глобальные модели обеспечивают лучшую обобщенность и экономию размера модели.
Однако в случаях, когда многие временные ряды имеют только некоторые общие черты поведения, более подходящей может быть модель глобально-локального типа. В такой модели используется одна модель с общими весами для захвата общих поведений по всем временным рядам, в то время как некоторые компоненты моделируются отдельно для каждого временного ряда.
В этом руководстве мы продемонстрируем пример глобального локального моделирования, отдельно моделируя компоненты тренда и сезонности для каждого временного ряда в наборе данных почасовых нагрузок региона ERCOT.
Сначала загружаем данные:
if"google.colab"instr(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 pdfrom neuralprophet import NeuralProphet, set_log_levelfrom neuralprophet import set_random_seedimport numpy as npset_random_seed(10)set_log_level("ERROR", "INFO")
Извлекаем названия регионов, которые позже будут использованы при создании модели.
Глобальные модели можно активировать, когда входные данные df функции имеют дополнительную колонку «ID», которая идентифицирует различные временные ряды (помимо типичной колонки «ds», содержащей временные метки, и колонки «y», содержащей наблюдаемые значения временного ряда). В нашем примере мы выбираем данные за трехлетний интервал (с 2004 по 2007 год).
Мы изменим тенденцию для СЕВЕРА и сезонность для ПОБЕРЕЖЬЯ.
Глобальное моделирование
Примечание: Обучение временного ряда, содержащего только компоненты тренда и сезонности, может привести к плохим результатам. Приведенный пример используется только для демонстрации новой функциональности локального моделирования множества временных рядов.
Когда входными данными для функции split_df является pd.DataFrame со столбцом ID, тренировочные и валидационные данные предоставляются в аналогичном формате. Для глобальных моделей входные данные обычно разделяются в соответствии с долей времени, охватывающей все временные ряды (по умолчанию, когда есть более одного ID и когда local_split=False). Если пользователь хочет разделить каждый временной ряд локально, параметр local_split должен быть установлен в значение True. В этом примере мы разделим наши данные на тренировочные и тестовые (с 33% долей тестовой выборки - 2 года на обучение и 1 год на тестирование).
После создания объекта NeuralProphet, модель может быть создана путем вызова функции fit
Убедитесь, что вы предоставляете данные, идентифицированные с ключами, связанными с соответствующими временными рядами поездов. Таким образом, подходящие параметры нормализации данных используются в процедурах после подгонки (т.е.,predict, test).
Мы сейчас построим прогнозируемые временные ряды и параметры для:
NORTH: С корректировкой тренда
COAST: С корректировкой сезонности
EAST: Без изменений к оригиналу
North
South
East
Metrics
MAE_val
RMSE_val
Loss_test
RegLoss_test
0
0.235438
0.267084
0.123413
0.0
Локальное моделирование тренда и сезонности
Мы повторим вышеописанный процесс, но для локального моделирования тренда и сезонности.
North
Coast
East
Metric
MAE_val
RMSE_val
Loss_test
RegLoss_test
0
0.18777
0.220333
0.084803
0.0
Заключение
Сравнивая локально-глобальную модель и глобальную модель, мы достигли более низкой ошибки с локально-глобальной моделью.
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") # устанавливаем бэкенд для визуализации графиков
df_train, df_test = m.split_df(df_global, valid_p=0.33, local_split=True) # разделяем данные на тренировочный и тестовый наборы
print(df_train.shape, df_test.shape) # выводим размеры тренировочного и тестового наборов
metrics = m.fit(df_train, freq="H") # обучаем модель на тренировочных данных с частотой "H" (час)
future = m.make_future_dataframe(df_test, n_historic_predictions=True) # создаем будущие даты на основе тестовых данных
forecast = m.predict(future) # делаем прогноз на будущее
m.plot(forecast[forecast["ID"] == "NORTH"]) # визуализация прогноза для региона NORTH
m.plot_parameters(df_name="NORTH") # визуализация параметров модели для региона NORTH
m.plot(forecast[forecast["ID"] == "COAST"]) # визуализация прогноза для региона COAST
m.plot_parameters(df_name="COAST") # визуализация параметров модели для региона COAST
m.plot(forecast[forecast["ID"] == "EAST"]) # визуализация прогноза для региона EAST
m.plot_parameters(df_name="EAST") # визуализация параметров модели для региона EAST
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) # предсказание на основе будущего фрейма данных
m.plot(forecast[forecast["ID"] == "NORTH"]) # построение графика прогноза для региона "NORTH"
m.plot_parameters(df_name="NORTH") # визуализация параметров модели для региона "NORTH"
m.plot(forecast[forecast["ID"] == "COAST"]) # визуализация прогноза для региона "COAST"
m.plot_parameters(df_name="COAST") # визуализация параметров модели для региона "COAST"
m.plot(forecast[forecast["ID"] == "EAST"]) # визуализация прогноза для региона "EAST"
m.plot_parameters(df_name="EAST") # визуализация параметров модели для региона "EAST"
test_metrics_local = m.test(df_test) # вычисление метрик качества модели на тестовом наборе данных
test_metrics_local # вывод результатов