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

Вы изучите следующие рецепты:

  • Разложение временных рядов с несколькими сезонными моделями с использованием MSTL
  • Прогнозирование с использованием нескольких сезонных закономерностей с использованием Модели ненаблюдаемых компонентов (UCM)
  • Прогнозирование временных рядов с несколькими сезонными закономерностями с помощью Prophet
  • Прогнозирование временных рядов с несколькими сезонными закономерностями с помощью NeuralProphet

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

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

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

Разложение временных рядов с несколькими сезонными закономерностями с использованием MSTL

Во временном ряду была одна сезонная закономерность, и вы могли разбить ее на три основные части: тренд, сезонная закономерность и остаток (остаток). Вы можете знать функцию seasonal_decompose и класс STL (разложение сезонного тренда с использованием лесса) из статистических моделей.

Таким образом, новый подход к декомпозиции временных рядов с множественной сезонностью был представлен в статье, опубликованной Бандарой, Хайндманом и Бергмейром, под названием MSTL: алгоритм декомпозиции сезонного тренда для временных рядов с множественными сезонными закономерностями.

Множественная декомпозиция STL (MSTL) является расширением алгоритма STL и аналогично аддитивной декомпозиции, но расширяет уравнение, чтобы включить несколько сезонных компонентов, а не только один:

Алгоритм итеративно подбирает разложение STL для каждого сезонного цикла (частота определена), чтобы получить разложенные сезонные компоненты
𝑆𝑡1 + 𝑆𝑡2 + ⋯ + 𝑆𝑡𝑛. После завершения итеративного процесса для каждого сезонного цикла оценивается компонент тренда. Если временной ряд не содержит сезонных компонентов, MSTL будет оценивать только тренд.

Как правило, высокочастотные данные демонстрируют несколько сезонных закономерностей. Например, почасовые временные ряды могут иметь дневную, недельную и годовую структуру. Вы начнете с импорта класса MSTL из statsmodels и изучите, как декомпозировать временные ряды энергопотребления.

Импортируйте класс MSTL:

from statsmodels.tsa.seasonal import MSTL

Создайте четыре переменные для хранения значений для расчетов дня, недели, месяца и года; таким образом, вы можете ссылаться на эти переменные. Например, поскольку данные почасовые, день представлен как 24 часа, а неделя как 24 X 7 или просто день X 7:

day = 24 week = day*7 
month = round(week*4.35) 
year = round(month*12) 
print(f''' 
day = {day} 
hours week = {week} 
hours month = {month} 
hours year = {year} hours 
''')

Начните с предоставления различных сезонных циклов, которые вы подозреваете, например, ежедневных и еженедельных сезонных моделей. Поскольку частота данных ежечасная, дневная картина наблюдается каждые 24 часа, а еженедельная — каждые 24 x 7 или 168 часов. Используйте метод подгонки, чтобы подогнать модель.

mstl = MSTL(df, periods=(day, week))
results = mstl.fit()

Объект results является экземпляром класса DecomposeResult, который предоставляет доступ к сезонным, трендовымирезидентным атрибуты. Атрибут seasonal будет отображать DataFrame с двумя столбцами, помеченными как seasonal_24 и seasonal_168.
Предыдущие пять подграфиков для наблюдаемых тренд, seasonal_24 ​​ (ежедневно), seasonal_168 (еженедельно) и resid (остальные) соответственно:

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

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

В целом, результаты (ежедневные и еженедельные) предполагают годовое влияние, указывающее на годовой сезонный характер. В разделе «Есть еще» вы узнаете, как вы можете раскрыть эту годовую закономерность (например, чтобы зафиксировать повторяющиеся закономерности каждый июль).

MSTL – это простой и интуитивно понятный алгоритм для разложения данных временных рядов с несколькими сезонными закономерностями. Параметр iterate в MSTL по умолчанию имеет значение iterate=2, которое представляет собой количество итераций, используемых алгоритмом для оценки сезонных компонентов. На каждой итерации алгоритм применяет алгоритм STL для оценки сезонной составляющей для каждого идентифицированного сезонного периода.

Вы обновите окна до [121, 121] для каждого сезонного компонента в следующем коде. Значения по умолчанию для окон: [11, 15]. Значение по умолчанию для итерации равно 2, и вы обновите его до 5.

mstl = MSTL(df, periods=(24, 24*7), iterate=4, windows=[121, 121])
results = mstl.fit()

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

Прогнозирование с использованием нескольких сезонных закономерностей с использованием модели ненаблюдаемых компонентов (UCM)

В предыдущем рецепте вы познакомились с MSTL для декомпозиции временных рядов с множественной сезонностью. Точно так же Модель ненаблюдаемых компонентов (UCM) – это метод декомпозиции временного ряда (с несколькими сезонными закономерностями), но, в отличие от MSTL, UCM также является моделью прогнозирования. Первоначально UCM был предложен в качестве альтернативы модели ARIMA и представлен Харви в книге Прогнозирование, модели структурных временных рядов и фильтр Калмана, впервые опубликованной в 1989 г. В отличие от модели ARIMA, UCM разлагает процесс временного ряда путем оценки его компонентов и не делает предположений относительно стационарности или распределения.

Бывают ситуации, когда невозможно сделать временной ряд стационарным, например, путем дифференцирования. Временной ряд также может содержать неравномерности и другие сложности. Именно здесь UCM выступает как более гибкая и интерпретируемая модель. UCM основан на идее скрытых переменных или ненаблюдаемых компонентов временного ряда, таких как уровень, тенденция и сезонность. Их можно оценить по наблюдаемой переменной. В statsmodels класс UnobservedComponents разлагает временной ряд на компонент тренда, сезонный компонент, циклический компонент и нерегулярный компонент или член ошибки. Уравнение можно обобщить следующим образом:

здесь 𝑦𝑡 — наблюдаемая переменная в момент времени t, а 𝑢𝑡, 𝛾𝑡, 𝑐𝑡 — тренд, сезонные и циклические компоненты. Член 𝜖𝑡 представляет собой нерегулярную составляющую (или возмущение). Вы также можете иметь несколько сезонов. Основная идея UCM заключается в том, что каждый компонент, называемый состоянием, моделируется вероятностным образом, поскольку он не наблюдается. UCM также может содержать компоненты авторегрессии и регрессии для учета их эффектов.

В этом рецепте вы будете использовать реализацию UCM в статистических моделях. Вы будете использовать тот же набор данных об энергопотреблении, который загружен в разделе «Технические требования». В рецепте Разложение временных рядов с несколькими сезонными закономерностями с помощью MSTL вы смогли разложить сезонную закономерность на ежедневные, недельные и годовые компоненты. Вы будете использовать эти знания в этом рецепте:

from statsmodels.tsa.statespace.structural import UnobservedComponents

UnobservedComponents принимают несколько параметров. Представляет интерес freq_seasonal, который берет словарь для каждого сезонного компонента частотной области, например, ежедневно, еженедельно и ежегодно. Вы передадите список пар ключ-значение для каждого периода. При желании в каждом словаре вы также можете передать пару ключ-значение для гармоник. Если значения гармоник не передаются, по умолчанию используется np.floor(period/2).

params = {'level':'dtrend',  'irregular':True,  
         'freq_seasonal':[{'period': day},{'period': week},
         {'period': year}],  
         'stochastic_freq_seasonal':[False, False, False]} 
model = UnobservedComponents(train, **params)

Теперь вы можете подогнать модель к обучающим данным, используя метод fit , а после завершения обучения вы можете просмотреть сводку модели, используя метод summary

results = model.fit()
results.summary()

Объекты результатов имеют тип UnobservedComponentsResultsWrapper, который предоставляет доступ к нескольким свойствам и методам, таким как plot_components и plot_diagnostics, и это лишь некоторые из них. plot_diagnostics используется для диагностики общей производительности модели по невязкам:

У нас было подобное наблюдение в предыдущем рецепте с использованием MSTL.

Наконец, используйте модель, чтобы сделать прогноз и сравнить ее с набором вне выборки (тестовые данные) и рассчитать RMSE и RMSPE, используя функции, импортированные из statsmodels. ранее в разделе Технические требования.
код здесь

rmspe(test['y'], prediction) 
>> 1.0676342700345198 
rmse(test['y'], prediction) 
>> 1716.1196099493693

Прогнозирование временных рядов с несколькими сезонными моделями с использованием Prophet

Цель этого рецепта — показать, как вы можете использовать Prophet для решения более сложного набора данных с несколькими сезонными закономерностями.

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

В этом рецепте вы продолжите использовать тот же набор данных о потреблении энергии (df DataFrame) и выполните аналогичное разделение для обучающего и тестового наборов.

from prophet import Prophet 
from prophet.plot import add_changepoints_to_plot
energy = df.copy() 
energy.reset_index(inplace=True) 
energy.columns = ['ds', 'y']
train = energy.iloc[:-month] 
test = energy.iloc[-month:]
model = Prophet().fit(train)

Используйте метод make_future_dataframe для расширения train DataFrame вперед на определенное количество периодов и с указанной частотой. В данном случае это будет количество тестовых наблюдений. Частота указывается как почасовая с freq= ‘H’.

n = len(test) 
future = model.make_future_dataframe(n, freq='H')
forecast = model.predict(future)

rmspe(test['y'].values, prediction.values) 
>> 1.2587190915113151 
rmse(test['y'].values, prediction.values) 
>> 1885.143242946697

Prophet автоматизировал многие аспекты построения и оптимизации модели, поскольку для параметров yearly_seasonality, weekly_seasonality и daily_seasonality по умолчанию было установлено значение auto, что позволяло Prophet определить, какие из них включить или выключить на основе данных. До сих пор вы использовали Prophet для временных рядов с одной сезонностью, а теперь снова для временных рядов с множественной сезонностью. Процесс обучения модели и составления прогнозов одинаков, что делает Prophet очень привлекательным вариантом из-за его последовательной структуры. код здесь

Прогнозирование временных рядов с несколькими сезонными моделями с использованием NeuralProphet

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

Prophet был построен поверх PyStan, библиотеки байесовского вывода, и является одной из основных зависимостей при установке Prophet. И наоборот, NeuralProphet основан на PyTorch и используется как среда глубокого обучения. Это позволяет NeuralProphet масштабироваться до больших наборов данных и, как правило, обеспечивает более высокую точность, чем Prophet. Как и метод Prophet, NeuralProphet выполняет настройку гиперпараметров и полностью автоматизирует многие аспекты прогнозирования временных рядов. В этом рецепте вы сравните результаты использования NeuralProphet и Prophet.

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

from neuralprophet import NeuralProphet
energy = df.copy() 
energy.reset_index(inplace=True) 
energy.columns = ['ds', 'y'] 
train = energy.iloc[:-month*2] 
val = energy.iloc[-month*2:-month] 
test = energy.iloc[-month:]
m = NeuralProphet() 
metrics = m.fit(train, validation_df=val)

Как и в случае с Prophet, вы будете использовать метод make_future_dataframe для расширения кадра данных train вперед на определенное количество периодов и с указанной частотой. В данном случае это будет общее количество наблюдений test и val:

n = len(test)+len(val) 
future = m.make_future_dataframe(df=train, periods=n) 
forecast = m.predict(df=future)
fig = m.plot_components(forecast)

rmspe(test['y'].values, prediction.values) 
>> 1.1729025662066894 
rmse(test['y'].values, prediction.values) 
>> 1796.2832495706689

В целом, как RMSE, так и RMSPE для NeuralProphet показывают, что модель превосходит Prophet.

Как и Prophet, NeuralProphet также разлагает временные ряды на составляющие. NeuralProphet может включать различные термины, такие как тренд, сезонность, авторегрессия (параметр n_lags), специальные события (метод add_events), регрессоры будущего (экзогенные переменные с методом add_future_regressor) и регрессоры с задержкой (метод add_lagged_ regressor). Часть авторегрессии основана на AR-Net, авторегрессивной нейронной сети. NeuralProphet позволяет добавлять повторяющиеся особые события — например, игру Суперкубка или день рождения. Процесс моделирования временных рядов аналогичен процессу в Prophet, который был создан по замыслу. Имейте в виду, что NeuralProphet был создан с нуля с использованием PyTorch и не является оболочкой для Prophet. код здесь