Прогнозирование временных рядов питон

Прогнозирование временных рядов — ARIMA, LSTM, Prophet с Python

В этой статье мы попытаемся в основном спрогнозировать данные временного ряда. Мы построим три разные модели с помощью Python и проверим их результаты. Мы будем использовать следующие модели: ARIMA (интегрированное скользящее среднее с авторегрессией), LSTM (нейронная сеть с краткосрочной памятью) и Facebook Prophet. Давайте начнем с ARIMA.

ARIMA (интегрированное скользящее среднее с авторегрессией)

ARIMA — это модель, которая используется для прогнозирования будущих тенденций на основе данных временных рядов. Это модельная форма регрессионного анализа.

  • AR (авторегрессия): модель, которая показывает изменяющуюся переменную, которая регрессирует на свои собственные запаздывающие / предыдущие значения.
  • I (интегрированный): дифференциация необработанных наблюдений, чтобы временные ряды стали стационарными.
  • MA (скользящее среднее): зависимость между наблюдением и остаточной ошибкой модели скользящего среднего.

Для моделей ARIMA стандартным обозначением будет ARIMA с p, d и q, где целочисленные значения заменяют параметры, чтобы указать тип используемой модели ARIMA.

  • p: количество наблюдений за запаздыванием в модели; также известный как порядок запаздывания.
  • d: количество раз, когда исходные наблюдения различаются; также называется степенью дифференциации.
  • q: размер окна скользящей средней; также известен как порядок скользящей средней.

Нейронная сеть LSTM

LSTM означает долгую краткосрочную память. Это модель или архитектура, расширяющая память повторяющихся нейронных сетей. Как правило, рекуррентные нейронные сети имеют «краткосрочную память» в том смысле, что они используют постоянную предыдущую информацию, которая будет использоваться в текущей нейронной сети. По сути, в данной задаче используется предыдущая информация. Это означает, что у нас нет списка всей предыдущей информации, доступной для нейронного узла. LSTM вводит долговременную память в рекуррентные нейронные сети. Это смягчает проблему исчезающего градиента, когда нейронная сеть перестает обучаться, потому что обновления различных весов в данной нейронной сети становятся все меньше и меньше. Для этого используется серия «ворот». Они содержатся в блоках памяти, которые связаны между собой слоями, например:

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

Пророк

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

ПРОГНОЗ

Читать набор данных

import numpy as np import pandas as pd from statsmodels.tsa.statespace.sarimax import SARIMAX from statsmodels.graphics.tsaplots import plot_acf,plot_pacf from statsmodels.tsa.seasonal import seasonal_decompose from pmdarima import auto_arima from sklearn.metrics import mean_squared_error from statsmodels.tools.eval_measures import rmse import warnings warnings.filterwarnings("ignore") df = pd.read_csv('monthly-beer-production-in-austr.csv') df.head()

df.Month = pd.to_datetime(df.Month) df = df.set_index("Month") df.head()

df.index.freq = 'MS' ax = df['Monthly beer production'].plot(figsize = (16,5), title = "Monthly Beer Production") ax.set(xlabel='Dates', ylabel='Total Production');

Когда мы смотрим на график, мы можем видеть, что в данных есть сезонность. Вот почему мы будем использовать SARIMA (сезонный ARIMA) вместо ARIMA.

Сезонный ARIMA — это расширение ARIMA, которое явно поддерживает одномерные данные временных рядов с сезонной составляющей. Он добавляет три новых гиперпараметра, чтобы указать авторегрессию (AR), разность (I) и скользящее среднее (MA) для сезонного компонента ряда, а также дополнительный параметр для периода сезонности.

Необходимо настроить четыре сезонных элемента, не являющихся частью ARIMA; это:
P: порядок сезонной авторегрессии.
D: порядок сезонной разницы.
Q: Порядок сезонного скользящего среднего.
m: количество временных шагов за один сезонный период.

a = seasonal_decompose(df["Monthly beer production"], model = "add") a.plot();

import matplotlib.pyplot as plt plt.figure(figsize = (16,7)) a.seasonal.plot();

Прогноз ARIMA

Давайте запустим функцию auto_arima (), чтобы получить наилучшие значения p, d, q, P, D, Q

auto_arima(df['Monthly beer production'], seasonal=True, m=12,max_p=7, max_d=5,max_q=7, max_P=4, max_D=4,max_Q=4).summary()

Как мы видим, лучшая модель arima, выбранная auto_arima (), — это SARIMAX (2, 1, 1) x (4, 0, 3, 12)

Читайте также:  Python file open функции

Давайте разделим данные на набор для обучения и тестирования.

train_data = df[:len(df)-12] test_data = df[len(df)-12:] arima_model = SARIMAX(train_data['Monthly beer production'], order = (2,1,1), seasonal_order = (4,0,3,12)) arima_result = arima_model.fit() arima_result.summary()

arima_pred = arima_result.predict(start = len(train_data), end = len(df)-1, typ="levels").rename("ARIMA Predictions") arima_pred

test_data['Monthly beer production'].plot(figsize = (16,5), legend=True) arima_pred.plot(legend = True);

arima_rmse_error = rmse(test_data['Monthly beer production'], arima_pred) arima_mse_error = arima_rmse_error**2 mean_value = df['Monthly beer production'].mean() print(f'MSE Error: \nRMSE Error: \nMean: ')

test_data['ARIMA_Predictions'] = arima_pred

Прогноз LSTM

Сначала мы масштабируем наши обучающие и тестовые данные с помощью MinMaxScaler.

from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() scaler.fit(train_data) scaled_train_data = scaler.transform(train_data) scaled_test_data = scaler.transform(test_data)

Перед созданием модели LSTM мы должны создать объект генератора временных рядов.

from keras.preprocessing.sequence import TimeseriesGenerator n_input = 12 n_features= 1 generator = TimeseriesGenerator(scaled_train_data, scaled_train_data, length=n_input, batch_size=1) from keras.models import Sequential from keras.layers import Dense from keras.layers import LSTM lstm_model = Sequential() lstm_model.add(LSTM(200, activation='relu', input_shape=(n_input, n_features))) lstm_model.add(Dense(1)) lstm_model.compile(optimizer='adam', loss='mse') lstm_model.summary()

lstm_model.fit_generator(generator,epochs=20)

losses_lstm = lstm_model.history.history['loss'] plt.figure(figsize=(12,4)) plt.xlabel("Epochs") plt.ylabel("Loss") plt.xticks(np.arange(0,21,1)) plt.plot(range(len(losses_lstm)),losses_lstm);

lstm_predictions_scaled = list() batch = scaled_train_data[-n_input:] current_batch = batch.reshape((1, n_input, n_features)) for i in range(len(test_data)): lstm_pred = lstm_model.predict(current_batch)[0] lstm_predictions_scaled.append(lstm_pred) current_batch = np.append(current_batch[:,1. ],[[lstm_pred]],axis=1)

Как вы знаете, мы масштабировали наши данные, поэтому нам нужно инвертировать их, чтобы увидеть верные прогнозы.

lstm_predictions = scaler.inverse_transform(lstm_predictions_scaled) lstm_predictions

test_data['LSTM_Predictions'] = lstm_predictions test_data

test_data['Monthly beer production'].plot(figsize = (16,5), legend=True) test_data['LSTM_Predictions'].plot(legend = True);

lstm_rmse_error = rmse(test_data['Monthly beer production'], test_data["LSTM_Predictions"]) lstm_mse_error = lstm_rmse_error**2 mean_value = df['Monthly beer production'].mean() print(f'MSE Error: \nRMSE Error: \nMean: ')

Прогноз пророка

df_pr = df.copy() df_pr = df.reset_index() df_pr.columns = ['ds','y'] # To use prophet column names should be like that train_data_pr = df_pr.iloc[:len(df)-12] test_data_pr = df_pr.iloc[len(df)-12:] from fbprophet import Prophet m = Prophet() m.fit(train_data_pr) future = m.make_future_dataframe(periods=12,freq='MS') prophet_pred = m.predict(future) prophet_pred.tail()

prophet_pred = pd.DataFrame() prophet_pred = prophet_pred.set_index("Date") prophet_pred.index.freq = "MS" prophet_pred

test_data["Prophet_Predictions"] = prophet_pred['Pred'].values import seaborn as sns plt.figure(figsize=(16,5)) ax = sns.lineplot(x= test_data.index, y=test_data["Monthly beer production"]) sns.lineplot(x=test_data.index, y = test_data["Prophet_Predictions"]);

prophet_rmse_error = rmse(test_data['Monthly beer production'], test_data["Prophet_Predictions"]) prophet_mse_error = prophet_rmse_error**2 mean_value = df['Monthly beer production'].mean() print(f'MSE Error: \nRMSE Error: \nMean: ')

rmse_errors = [arima_rmse_error, lstm_rmse_error, prophet_rmse_error] mse_errors = [arima_mse_error, lstm_mse_error, prophet_mse_error] errors = pd.DataFrame() plt.figure(figsize=(16,9)) plt.plot_date(test_data.index, test_data["Monthly beer production"], linestyle="-") plt.plot_date(test_data.index, test_data["ARIMA_Predictions"], linestyle="-.") plt.plot_date(test_data.index, test_data["LSTM_Predictions"], linestyle="--") plt.plot_date(test_data.index, test_data["Prophet_Predictions"], linestyle=":") plt.legend() plt.show()

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

Источник

Оцените статью