统计模型:使用ARIMA实现直接递归的多步预测策略

时间:2018-10-30 12:42:03

标签: python time-series statsmodels forecasting forecast

我目前正在尝试使用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次。因此,无论此方法有多小,它所能节省的性能都会对其产生影响。

1 个答案:

答案 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,只有一个模型。