我目前正在尝试使用statsmodels ARIMA库来实现直接和递归多步预测策略,并且提出了一些问题。
递归的多步预测策略将是训练一个一步模型,预测下一个值,将预测值附加到输入到预测方法中的外生值的末尾并重复。这是我的递归实现:
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]
让我特别困惑的是,该模型是否应该对所有预测仅拟合一次,还是应该对多次预测进行多次拟合才能进行一次拟合?从Souhaib Ben Taieb's doctoral thesis (page 35 paragraph 3)得出的结论是,直接模型将估计H个模型,其中H是预测范围的长度,因此在我的预测范围为26个的示例中,应该估计26个模型,而不仅仅是一个。如上所示,我当前的实现仅适合一种模型。
我不明白的是,如果我在相同的训练数据上多次调用ARIMA.fit()方法,我将得到一个模型,该模型将得到与预期的正常随机变化之外的任何其他拟合值?
我的最后一个问题是关于优化。使用诸如前向验证之类的方法在统计上给了我非常重要的结果,但是对于许多时间序列而言,这在计算上非常昂贵。已经使用joblib并行循环执行功能调用了上述两种实现,这大大减少了我的笔记本电脑的运行时间。但是,我想知道关于上述实现是否可以做任何事情以使它们更加有效。在约2000个单独的时间序列中运行这些方法时(所有序列总共约500,000个数据点),运行时间为10小时。我已经分析了代码,大部分执行时间都花在statsmodels库中,这很好,但是walk_forward_validation()方法的运行时间与ARIMA.fit()之间存在差异。这是可以预期的,因为显然walk_forward_validation()方法除了调用fit方法外还可以做其他事情,但是如果可以更改其中的任何内容以加快执行时间,请告诉我。
此代码的想法是找到每个时间序列的最佳arima顺序,因为单独研究2000个时间序列是不可行的,因此walk_forward_validation()方法每个时间序列称为27次。大约是27,000次。因此,无论此方法有多小,它所能节省的性能都会对其产生影响。
答案 0 :(得分:2)
通常,ARIMA只能执行递归预测,而不能执行直接预测。可能需要对ARIMA的变体进行一些研究以进行直接预测,但不会在Statsmodels中实现。在statsmodels中(或在R auto.arima()中),当您为h> 1设置一个值时,它仅执行递归预测即可到达该值。
据我所知,还没有标准的预测库实现直接预测,您将不得不自己编写代码。
根据Souhaib Ben Taieb的博士论文(第35页第3段),提出直接模型将估计H个模型,其中H是预测范围的长度,因此在我的示例中,预测范围为26、26个模型应该估计而不是一个。
我还没有阅读Ben Taieb的论文,但是从his paper "Machine Learning Strategies for Time Series Forecasting"开始,对于直接预测,只有一个模型针对一个H值。因此对于H = 26,将只有一个模型。如果需要为1到H之间的每个值进行预测,将有H个模型,但是对于一个H,只有一个模型。