При использовании одной модели прогнозирования с общими весами на наборе данных, состоящем из множества временных рядов, можно достичь создания так называемой глобальной модели. Она особенно полезна в случаях, когда один временной ряд может не отражать всю динамику временных рядов. Кроме того, глобальные модели обеспечивают лучшую обобщенность и экономию размера модели.
Однако в случаях, когда многие временные ряды имеют только некоторые общие черты поведения, более подходящей может быть модель глобально-локального типа. В такой модели используется одна модель с общими весами для захвата общих поведений по всем временным рядам, в то время как некоторые компоненты моделируются отдельно для каждого временного ряда.
В этом руководстве мы продемонстрируем пример глобального локального моделирования, отдельно моделируя компоненты тренда и сезонности для каждого временного ряда в наборе данных почасовых нагрузок региона 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")
Извлекаем названия регионов, которые позже будут использованы при создании модели.
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()# визуализируем данные для региона NORTHdf_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 # вывод результатов