В настоящее время я пытаюсь реализовать стратегии прямого и рекурсивного многоэтапного прогнозирования с использованием библиотеки ARIMA statsmodels, и это подняло несколько вопросов.
Стратегия рекурсивного многошагового прогнозирования - это обучение одношаговой модели, прогнозирование следующего значения, добавление прогнозируемого значения в конец моих экзогенных значений, вводимых в метод прогнозирования, и повторение. Это моя рекурсивная реализация:
def arima_forecast_recursive(history, horizon=1, config=None):
# make list so can add / remove elements
history = history.tolist()
model = ARIMA(history, order=config)
model_fit = model.fit(trend='nc', disp=0)
for i, x in enumerate(history):
yhat = model_fit.forecast(steps=1, exog=history[i:])
yhat.append(history)
return np.array(yhat)
def walk_forward_validation(dataframe, config=None):
n_train = 52 # Give a minimum of 2 forecasting periods to capture any seasonality
n_test = 26 # Test set should be the size of one forecasting horizon
n_records = len(dataframe)
tuple_list = []
for index, i in enumerate(range(n_train, n_records)):
# create the train-test split
train, test = dataframe[0:i], dataframe[i:i + n_test]
# Test set is less than forecasting horizon so stop here.
if len(test) < n_test:
break
yhat = arima_forecast_recursive(train, n_test, config)
results = smape3(test, yhat)
tuple_list.append(results)
return tuple_list
Точно так же, чтобы выполнить прямую стратегию, я бы просто подгонял свою модель к имеющимся данным обучения и использовал ее для одновременного прогнозирования общего многоэтапного прогноза. Я не уверен, как этого добиться с помощью библиотеки statsmodels.
Моя попытка (которая дает результаты) ниже:
def walk_forward_validation(dataframe, config=None):
# This currently implements a direct forecasting strategy
n_train = 52 # Give a minimum of 2 forecasting periods to capture any seasonality
n_test = 26 # Test set should be the size of one forecasting horizon
n_records = len(dataframe)
tuple_list = []
for index, i in enumerate(range(n_train, n_records)):
# create the train-test split
train, test = dataframe[0:i], dataframe[i:i + n_test]
# Test set is less than forecasting horizon so stop here.
if len(test) < n_test:
break
yhat = arima_forecast_direct(train, n_test, config)
results = smape3(test, yhat)
tuple_list.append(results)
return tuple_list
def arima_forecast_direct(history, horizon=1, config=None):
model = ARIMA(history, order=config)
model_fit = model.fit(trend='nc', disp=0)
return model_fit.forecast(steps=horizon)[0]
Что меня особенно смущает, так это то, что модель должна подходить один раз для всех прогнозов или несколько раз, чтобы сделать один прогноз в многошаговом прогнозе? Взятый из докторской диссертации Соухаиба Бен Тайба (стр. 35, параграф 3) , представляется, что прямая модель будет оценивать H-модели, где H - длина горизонта прогноза, поэтому в моем примере с горизонтом прогноза 26 26 моделей должны оцениваться вместо одной. Как показано выше, моя текущая реализация подходит только для одной модели.
Что я не понимаю, так это то, как, если я вызову метод ARIMA.fit () несколько раз для одних и тех же данных обучения, я получу модель, которая мне подойдет, которая будет отличаться от ожидаемого нормального стохастического отклонения?
Мой последний вопрос касается оптимизации. Использование такого метода, как валидация, дает мне статистически очень важные результаты, но для многих временных рядов это очень дорого в вычислительном отношении. Обе вышеперечисленные реализации уже вызваны с использованием функциональности выполнения параллельного цикла joblib, что значительно сократило время работы моего ноутбука. Тем не менее, я хотел бы знать, можно ли что-либо сделать в отношении вышеуказанных реализаций, чтобы сделать их еще более эффективными. При использовании этих методов для ~ 2000 отдельных временных рядов (всего ~ 500 000 точек данных для всех рядов) время выполнения составляет 10 часов. Я профилировал код, и большая часть времени выполнения была потрачена в библиотеке statsmodels, что хорошо, но есть расхождение между временем выполнения метода walk_forward_validation () и ARIMA.fit (). Это ожидается, поскольку очевидно, что метод walk_forward_validation () делает что-то, кроме простого вызова метода fit, но если что-то в нем можно изменить, чтобы ускорить время выполнения, пожалуйста, дайте мне знать.
Идея этого кода состоит в том, чтобы найти оптимальный порядок аримы для временных рядов, поскольку не представляется возможным исследовать 2000 временных рядов индивидуально, и поэтому метод walk_forward_validation () вызывается 27 раз за временной ряд. Таким образом, примерно в 27000 раз. Поэтому любое снижение производительности, которое можно найти в этом методе, будет иметь влияние независимо от того, насколько оно мало.