我目前正在尝试使用statsmodels ARIMA库实现直接和递归多步预测策略,这引发了一些问题。
递归多步预测策略将训练一个单步模型,预测下一个值,将预测值添加到输入到预测方法中的外生值的末尾并重复此操作。 这是我的递归实现:
类似地,要执行直接策略,我只需要在可用的训练数据上适配我的模型,并使用该模型一次性预测总多步预测。我不确定如何使用statsmodels库实现这一点。
我的尝试(可以产生结果)如下:
我困惑的是模型是应该只拟合一次来进行所有预测,还是为了进行多步预测而多次拟合?从Souhaib Ben Taieb博士论文(第35页第3段)中可以看出,直接模型将会估计H个模型,其中H是预测时间跨度的长度,因此在我的例子中,如果预测时间跨度为26,则需要估计26个模型而不仅仅是一个。如上所示,我目前的实现只拟合了一个模型。
我不理解的是,如果我在相同的训练数据上多次调用ARIMA.fit()方法,那么我将得到一个与预期正常随机变化之外任何不同的拟合吗?
我的最后一个问题与优化有关。使用像前向验证这样的方法给我带来了非常显著的统计结果,但对于许多时间序列来说,它的计算成本非常高。上述两种实现已经使用了joblib并行循环执行功能进行调用,这显著减少了我的笔记本电脑运行时间。然而,我想知道是否有任何方法可以使上述实现更加高效。当针对约2000个单独的时间序列(所有系列总共约500,000个数据点)运行这些方法时,运行时间为10小时。我已经对代码进行了分析,大部分执行时间都花费在statsmodels库中,这很好,但是walk_forward_validation()方法和ARIMA.fit()的运行时间之间存在差异。这是预期的,因为显然walk_forward_validation()方法不仅仅是调用fit方法,但如果其中的任何内容都可以更改以加快执行时间,请告诉我。这段代码的想法是找到每个时间序列的最佳ARIMA顺序,因为逐个调查2000个时间序列是不可行的,因此会对每个时间序列调用27次walk_forward_validation()方法。因此,无论发现该方法内部的任何性能节省有多小,都将产生影响。
递归多步预测策略将训练一个单步模型,预测下一个值,将预测值添加到输入到预测方法中的外生值的末尾并重复此操作。 这是我的递归实现:
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博士论文(第35页第3段)中可以看出,直接模型将会估计H个模型,其中H是预测时间跨度的长度,因此在我的例子中,如果预测时间跨度为26,则需要估计26个模型而不仅仅是一个。如上所示,我目前的实现只拟合了一个模型。
我不理解的是,如果我在相同的训练数据上多次调用ARIMA.fit()方法,那么我将得到一个与预期正常随机变化之外任何不同的拟合吗?
我的最后一个问题与优化有关。使用像前向验证这样的方法给我带来了非常显著的统计结果,但对于许多时间序列来说,它的计算成本非常高。上述两种实现已经使用了joblib并行循环执行功能进行调用,这显著减少了我的笔记本电脑运行时间。然而,我想知道是否有任何方法可以使上述实现更加高效。当针对约2000个单独的时间序列(所有系列总共约500,000个数据点)运行这些方法时,运行时间为10小时。我已经对代码进行了分析,大部分执行时间都花费在statsmodels库中,这很好,但是walk_forward_validation()方法和ARIMA.fit()的运行时间之间存在差异。这是预期的,因为显然walk_forward_validation()方法不仅仅是调用fit方法,但如果其中的任何内容都可以更改以加快执行时间,请告诉我。这段代码的想法是找到每个时间序列的最佳ARIMA顺序,因为逐个调查2000个时间序列是不可行的,因此会对每个时间序列调用27次walk_forward_validation()方法。因此,无论发现该方法内部的任何性能节省有多小,都将产生影响。