Прогнозирование временных рядов с использованием моделей AR, MA и ARIMA.

«Если вы можете заглянуть в семена времени и сказать, какое зерно будет расти, а какое нет, то говорите со мной. «- Уильям Шекспир

Введение

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

Данные временного ряда Y t - это случайная величина, обычно собираемая через регулярные промежутки времени и в хронологическом порядке. Если данные временного ряда содержат наблюдения только одной переменной (например, спроса на продукт во время t), то они называются данными одномерного временного ряда. Если данные состоят из нескольких переменных, например, спрос на продукт в момент t, цена во время t, сумма денег, потраченная компанией на продвижение в время t, цена конкурентов в момент t и т. д., тогда это называется данными многомерного временного ряда.

Данные временного ряда можно разбить на четыре следующих компонента:

1. Компонент тренда (T t ): Тренд - это последовательное долгосрочное движение данных вверх или вниз. Т

2. Сезонный компонент (S t ): Сезонный компонент (измеряется с помощью индекса сезонности) - это повторяющееся движение вверх или вниз (или колебания) от тренда, возникающего в пределах календарный год с фиксированными интервалами (т.е. время между сезонами фиксировано), например сезоны, кварталы, месяцы, дни недели и т. д.

3. Циклический компонент (C t ): Циклический компонент - это колебание вокруг линии тренда с произвольным интервалом (т. е. , время между циклами является случайным), что происходит из-за макроэкономических изменений, таких как рецессия, безработица и т. д. Циклические колебания имеют повторяющиеся модели со временем между повторениями более года. Основное различие между сезонными колебаниями и циклическими колебаниями заключается в том, что сезонные колебания происходят в фиксированный период в пределах календарного года, тогда как циклические колебания имеют случайное время между колебаниями. То есть периодичность сезонных колебаний постоянна, а периодичность циклических колебаний непостоянна.

4. Нерегулярный компонент (I t ): Нерегулярный компонент - это белый шум или случайные некоррелированные изменения, которые следуют нормальному распределению со средним значением 0. и постоянная дисперсия.

Скользящая средняя

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

import pandas as pd
wsb_df = pd.read_csv(‘wsb.csv’) 
wsb_df.head(10)

В Pandas есть функция Rolling (), которую можно использовать с агрегатной функцией, такой как mean (), для вычисления скользящего среднего для временного окна.

wsb_df[‘mavg_12’] = wsb_df[‘Sale Quantity’].rolling(window = 12). mean().shift(1)

Чтобы отобразить значения с точностью до 2 десятичных знаков, мы можем использовать pd.set_option и плавающий формат% .2f. Теперь распечатайте прогнозируемое значение, начиная с месяца 37.

pd.set_option(‘display.float_format’, lambda x: ‘%.2f’ % x) wsb_df[[‘Sale Quantity’, ‘mavg_12’]][36:]

Прогнозируемые значения на основе прогнозирования скользящего среднего

plt.figure(figsize=(10,4)) 
plt.xlabel(“Months”) 
plt.ylabel(“Quantity”) 
plt.plot(wsb_df[‘Sale Quantity’][12:]); 
plt.plot(wsb_df[‘mavg_12’][12:], ‘.’);
plt.legend();

Средняя абсолютная ошибка в процентах

Средняя абсолютная процентная ошибка (MAPE) - это средняя абсолютная процентная ошибка. Поскольку MAPE безразмерен, его можно использовать для сравнения разных моделей с разным масштабом. Давайте определим метод для MAPE:

import numpy as np
def get_mape(actual, predicted):
    y_true, y_pred = np.array(actual), np.array(predicted)
    return np.round( np.mean(np.abs((actual - predicted) / actual)) 
    *100,2)   

Давайте вызовем вышеуказанный метод, используя указанный выше DataFrame. «Объем продажи» передается как фактическое, а mavg_12 - как прогнозируемые значения. Записи с 37-го месяца используются для расчета MAPE.

get_mape( wsb_df[‘Sale Quantity’][36:].values, wsb_df[‘mavg_12’][36:].values)

MAPE в этом случае составляет 14.04. Таким образом, прогнозирование с использованием скользящего среднего дает нам MAPE 14,04%.

РАЗЛОЖЕНИЕ ВРЕМЕННОГО РЯДА

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

Yt =Tt +St +Ct +It

Аддитивные модели предполагают, что сезонная и циклическая составляющие не зависят от составляющей тренда. Аддитивные модели не очень распространены, поскольку во многих случаях сезонная составляющая может зависеть от тренда. Мультипликативная модель временных рядов задается как
Yt = Tt × St × Ct × It

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

Для декомпозиции данных временного ряда мы можем использовать следующие библиотеки:

  1. statsmodel.tsa предоставляет различные функции для анализа временных рядов .
  2. Season_decompose () в statsmodel.tsa.seasonal разделяет временной ряд на тренд, сезонность и остатки. Принимает параметры периодичности; например, для ежемесячных данных частота составляет 12.
from statsmodels.tsa.seasonal import seasonal_decompose
ts_decompse = seasonal_decompose(np.array(wsb_df[‘Sale Quantity’]), model=’multiplicative’,freq = 12)
## Plotting the deocomposed time series components
ts_plot = ts_decompose.plot()

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

wsb_df[‘seasonal’] = ts_decompse.seasonal 
wsb_df[‘trend’] = ts_decompse.trend

АВТОРЕГРЕССИВНЫЕ ИНТЕГРИРОВАННЫЕ СРЕДНИЕ МОДЕЛИ (ARIMA)

Модели авторегрессии (AR) и скользящего среднего (MA) - популярные модели, которые часто используются для прогнозирования. Модели AR и MA объединяются для создания таких моделей, как модели авторегрессивного скользящего среднего (ARMA) и авторегрессивного интегрированного скользящего среднего (ARIMA).

ACF: - это столбчатая диаграмма коэффициентов корреляции между временным рядом и его запаздыванием. Она помогает определить значение p или Термин AR. Чтобы построить график автокорреляции, используйте:

statsmodels.graphics.tsaplots.plot_acf

PACF: график частных коэффициентов корреляции между сериями и собственными лагами. Помогает определить значение q или члена скользящей средней. Чтобы построить график частичной автокорреляции, используйте:

statsmodels.graphics.tsaplots.plot_pacf

Авторегрессивное скользящее среднее (ARMA) представляет собой комбинацию авторегрессивного и скользящего среднего процесса. Процесс ARMA (p, q) объединяет процессы AR (p) и MA (q). p и q в процессе ARMA можно идентифицировать с помощью следующих правил большого пальца:

  1. Значения автокорреляции значимы для первых значений q (первые q запаздывания) и обрезаются до нуля.
  2. Значения частичной автокорреляции значимы для первых значений p и обрезаются до нуля.

Модели ARMA можно использовать только тогда, когда данные временного ряда являются стационарными. Модели ARIMA используются, когда данные временного ряда нестационарны. Данные временного ряда называются стационарными, если среднее значение, дисперсия и ковариация постоянны во времени. ARIMA состоит из следующих трех компонентов и представляется как ARIMA (p, d, q), где d - это Компонент интеграции. Возьмем пример данных магазина:

store_df = pd.read_excel(‘store.xls’)
store_df.head(5)

store_df.info()

Набор данных содержит данные о потребности в день за 115 дней. Мы можем преобразовать столбец в индекс DateTime, который является вводом по умолчанию для моделей временных рядов. Создание индекса DataTime гарантирует, что данные упорядочены по дате или времени. Наконец, постройте график зависимости спроса от даты с помощью метода plot ():

store_df.set_index(pd.to_datetime(store_df.Date),inplace=True) store_df.drop(‘Date’, axis = 1, inplace = True)
store_df[-5:]

plt.figure( figsize=(10,4)) 
plt.xlabel( “Date” ) 
plt.ylabel(“Demand” ) 
plt.plot( store_df.demand );

Тест Дики-Фуллера

Мы можем использовать тест Дики-Фуллера, чтобы проверить, является ли временной ряд стационарным или нет. statsmodels.tsa.stattools.adfuller - это тест Дики-Фуллера, который возвращает статистику теста и значение p для проверки нулевой гипотезы. Если значение p меньше 0,05, временной ряд является стационарным.

from statsmodels.tsa.stattools import adfuller
def adfuller_test(ts):
    adfuller_result = adfuller(ts, autolag=None) 
    adfuller_out = pd.Series(adfuller_result[0:4],
                      index=[‘Test Statistic’, ‘p-value’,
                             ‘Lags Used’,
                             ‘Number of Observations Used’])
    print(adfuller_out) 
    adfuller_text(stone_df.demand)

Значение p (›0,05) указывает, что мы не можем отклонить нулевую гипотезу и, следовательно, ряд не является стационарным. Различие исходных временных рядов - это обычный подход для преобразования нестационарного процесса в стационарный (так называемый разностная стационарность).

store_df[‘demand_diff’] = store_df.demand - store_df.demand.shift(1)    store_df.head(5)

Разница для первого дня составляет nan, поскольку у нас нет спроса в предыдущие дни. Мы можем исключить это значение из наблюдения до проверки стационарности.

store_diff_df = store_df.dropna()
plt.figure(figsize=(10,4)) 
plt.xlabel(“Date”) 
plt.ylabel(“First Order Differences”) 
plt.plot( store_diff_df.demand_diff);

Опять же, из тенденции не очень очевидно, является ли ряд стационарным или нет. Нам нужно будет построить график АКФ, чтобы проверить:

acf_plot = plot_acf(store_df.demand_diff.dropna(), lags=10)

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

store_train = store_df[0:100] 
store_test = store_df[100:]
arima = ARIMA(store_train.demand.astype(np.float64).as_matrix(), order = (1,1,1))
arima_model = arima.fit() 
arima_model.summary2()

Метод прогноз () принимает количество будущих периодов (шагов) для прогнозирования значений и возвращает прогнозируемые значения вместе со стандартной ошибкой и доверительным интервалом прогнозов.

store_predict, stderr, ci = arima_model.forecast(steps = 15) store_predict

get_mape(store_df.demand[100:], store_predict)

24.17: точность прогноза модели ARIMA с использованием разности первого порядка.