跳至内容
数据科学

ARIMAX:如何利用外生变量进行时间序列预测

了解 ARIMAX 如何通过外部预测变量扩展 ARIMA,理解其参数与假设,并使用 statsmodels 在 Python 中构建预测模型。
Vinod Chugani's photo
Vinod Chugani
已更新 · 9分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

设想您在预测每月用电需求。您已经有一个不错的 ARIMA 模型,捕捉到了序列的自相关和趋势。然后一场热浪来袭,您的预测偏差了 15%。变的不是序列,而是天气。这正是 ARIMAX 的用武之地:当外部因素对波动的影响与序列自身历史同样重要时的时间序列预测。

我们将介绍什么是 ARIMAX、它与 ARIMA 和 SARIMAX 的区别,以及何时该优先选择其中之一。我们还将通过一个完整的 Python 实战,涵盖数据准备、模型拟合、诊断与预测评估,方便您学以致用。

什么是 ARIMAX?

ARIMAX 是“自回归差分移动平均带外生变量”(AutoRegressive Integrated Moving Average with eXogenous variables)的缩写。 它是一个 ARIMA 模型,同时接受外部输入,即来自目标序列之外的预测变量。典型示例包括:广告投放、气温、促销标记、利率等。

一般记作 ARIMAX(p, d, q),并带有一个或多个外生回归变量。p、d、q 与 ARIMA 中含义相同:自回归阶数、差分阶数、移动平均阶数。字母 “X” 表示您可以传入其他您认为会影响目标的列。有一点需要提前说明:一些软件包将 ARIMAX 实现为“带 ARIMA 误差项的回归”模型,而不是把外部变量当作直接的自回归输入。这在数学上差别细微,但会影响您对系数的解读。我们在查看 statsmodels 输出时会回到这一点。

ARIMAX 的工作原理

ARIMAX 融合了两方面:序列自身的“记忆”,以及外部变量的解释力。

AR、I、MA 组件

AR(自回归)组件使用目标序列的滞后值来预测当前值。如果上个月销量很高,这一事实就很重要。

I(差分)组件通过差分去除趋势或单位根,使序列平稳。

MA(移动平均)组件利用过去的预测误差来修正模型一直犯的系统性错误。

这三者结合能够处理典型时间序列中的主要驱动因素:趋势、周期以及残差中的自相关。

外生变量的作用

外生变量提供了序列自身历史无法提供的信息。预测销量时,历史销量能告诉您常见模式。但降价或竞争对手入场是新增信息。模型会在同时考虑误差自相关的情况下,为每个外部预测变量估计一个系数。

实用解读是:如果目标序列主要由其自身的过去值解释,且没有可靠的外部预测变量,那么用纯 ARIMA 就足够了。但当您知道有外部因素在发挥作用,且在预测时确实能拿到这些预测变量的未来值时,ARIMAX 往往能给出更准确的预测。

ARIMA vs. ARIMAX vs. SARIMAX

SARIMAX 在 SARIMA 的基础上加入外生变量。实际中,Python 对 ARIMAX 的大多数实现都通过 statsmodels 的 SARIMAX() 完成,将季节性阶数设为零。

这不是权宜之计,而是标准做法。若序列有明显季节性或需要外部回归变量,SARIMAX 往往是首选,因为它能干净地同时处理这两点。需要注意的是:“ARIMAX” 与 “SARIMAX” 并非在所有库中都可以互换。在一些包中,无季节项的 SARIMAX 与 ARIMAX 在功能上等同;在另一些包中,它们在外生变量如何进入似然函数方面存在差异。请查阅您所用工具的文档。

何时使用 ARIMAX

通常取决于一件事:您是否拥有可能影响目标的外部预测变量,并且在需要做预测时能否拿到它们的未来值?

ARIMAX 能增值的情境

典型场景包括:带促销标记或价格变化的销量预测、带气温输入的能源需求、带投放费用的站点流量,以及与利率数据并行的经济指标。在这些情境中,外部变量提供了序列自身无法生成的信息。

当外部预测变量不可用、不可靠,或并未提升样本外准确率时,纯 ARIMA 或许就足够了。引入只带来噪声而无信号的预测变量于事无补。输入越多并不保证预测越好。在采用某个预测变量前,请先在留出数据上评估它。

关于因果的一句话

预测变量与目标之间的关系并不意味着因果。ARIMAX 是预测框架,它估计的是相关性。如果广告投入与销量在 12 月同时上升,模型可能会捕捉到这种关系,但并不会告诉您广告导致了增长。若您用预测来指导决策而非仅仅预测结果,这一区别至关重要。呈现结果时值得明确说明。

如何在 Python 中构建 ARIMAX 模型

下面进入实战。

我们使用一个可复现的示例:每月冰淇淋销量(售出数量),以气温(°C)和促销标记为外生预测变量。数据集覆盖 48 个月,其中 36 个月用于训练,12 个月用于评估。

准备数据

首先加载或构造一个具有一致月度日期索引的 DataFrame。确定目标变量与外生列,然后按日期对齐。在划分数据之前处理缺失值。不要跨训练/测试边界进行插补,否则会引入泄漏。

需要尽早牢记的原则:训练时传入了哪些外生值,预测时就需要提供相应的未来值。如果拿不到未来的气温预测,就不能把气温当作预测变量。这绝非小注脚——它会直接排除很多候选变量。

import pandas as pd
import numpy as np
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.tsa.stattools import adfuller
from sklearn.metrics import mean_absolute_error

# Construct a sample monthly dataset
np.random.seed(42)
dates = pd.date_range(start="2020-01", periods=48, freq="MS")
temperature = 15 + 10 * np.sin(np.linspace(0, 4 * np.pi, 48)) + np.random.normal(0, 1, 48)
promotion = np.where((np.arange(48) % 6 == 0), 1, 0)
sales = (
    500
    + 8 * temperature
    + 150 * promotion
    + np.cumsum(np.random.normal(0, 10, 48))
)

df = pd.DataFrame({"sales": sales, "temperature": temperature, "promotion": promotion}, index=dates)

# Train/test split
train = df.iloc[:36]
test = df.iloc[36:]

对于 statsmodels 的估计通常不需要缩放,但当各预测变量量纲差异很大时,缩放有助于数值稳定性。是否缩放取决于判断。

检查序列与预测变量

在选择模型参数前,先对目标序列做可视化检查并进行平稳性检验。增广 Dickey-Fuller(ADF)检验是标准做法。p 值低于 0.05 表明序列平稳,通常不需要差分(d=0)。若序列有明显趋势,通常设置 d=1。检验只是一个输入;领域知识与目视检查同样重要。

也要检查预测变量:它们是否与目标对齐?是否存在某个预测变量在预测日期之后才被测量的可能?在月初之前设定的促销标记没问题;当月的营收则不行。

选择候选参数并拟合模型

ACF 与 PACF 图有助于为 p 与 q 提供候选值。PACF 在滞后 1 处显著尖峰且 ACF 逐渐衰减通常提示 AR(1);反过来则提示 MA(1)。在训练数据上用 AIC 或 BIC 比较少量候选模型,测试集仅用于最终评估。

# Fit ARIMAX(1,1,1) via SARIMAX with no seasonal order
exog_train = train[["temperature", "promotion"]]
exog_test = test[["temperature", "promotion"]]

model = SARIMAX(
    train["sales"],
    exog=exog_train,
    order=(1, 1, 1),
    seasonal_order=(0, 0, 0, 0),
    trend="n"
)
result = model.fit(disp=False)
print(result.summary())

summary() 输出会同时显示 ARIMA 系数与外生变量的系数。气温系数告诉您,在自回归结构已考虑序列自身动量之后,气温每升高一度与销量水平变化之间的关联程度。需要了解的一点是:statsmodels 采用“带 ARIMA 误差的回归”表述方式,这意味着差分(d=1)施加在误差过程中,而不是直接施加在回归方程上。该系数表示对销量水平的影响,与 d 无关。在采用传递函数(transfer-function)表述的 ARIMAX(一些其他包使用)中,d=1 会让系数反映对“变化量”而非“水平”的影响。这一区别容易让人踩坑,因此请务必查阅所用工具的文档。

检查残差并评估预测

残差应当近似白噪声。检查残差的 ACF 图,确认是否仍有自相关。若出现显著尖峰,说明模型遗漏了结构。如果在季节性滞后处看到系统性模式,请改用带季节阶数的 SARIMAX。

# Generate out-of-sample predictions
predictions = result.forecast(steps=12, exog=exog_test)

# Evaluate
mae = mean_absolute_error(test["sales"], predictions)

# Naive baseline: forecast each period using the previous period's actual value
naive_forecast = np.concatenate([[train["sales"].iloc[-1]], test["sales"].values[:-1]])
naive_mae = mean_absolute_error(test["sales"], naive_forecast)

print(f"ARIMAX MAE: {mae:.1f}")
print(f"Naive MAE:  {naive_mae:.1f}")

将 ARIMAX 的 MAE 与天真基线(用前一期数值作预测)比较。如果 ARIMAX 在测试集上未胜过天真模型,这就是一个有意义的结果:额外复杂性并不值得。我见过这种情况比您想象的更常见,尤其当外生预测变量在样本内看起来很“干净”,但实际上更嘈杂时。

预测未来值

在训练期之外做预测与样本外评估相同:在调用 forecast() 时提供未来的外生变量值。对于促销标记,这通常比较简单,因为您事先知道促销日程。对于气温,通常需要天气预报或历史季节性均值。

请分清一点:statsmodels 返回的置信区间是以您提供的预测变量值为条件的。它们并未计入这些预测变量本身的不确定性。如果您的气温预测存在不确定性,真实的预测不确定性会比区间显示的更宽。在对可能据此行动的受众呈现结果时,值得说明这一点。

常见挑战与局限

上述实现是理想路径。以下是常见的失效点。

  • 未来预测变量可能未知:这是最常见的实际障碍。如果无法可靠获得外生变量的未来值,就无法使用它们。用明天的气温来预测能源需求需要气温预测,而不是昨天的气温。
  • 预测变量可能泄漏信息:在预测日期之后才被测量的变量,会让样本内评估看起来比实际好得多。务必注意预测变量的时间戳究竟对应何时。
  • 关系可能变化:用历史数据估计出的系数未必在未来仍然成立。稳定两年的价格弹性可能在市场冲击后发生转变,2024 与 2025 年就足以让这不再只是理论。定期重新估计模型是好习惯。
  • 相关预测变量使解读更复杂:高度共线的输入会让单个系数估计不稳定。这未必会伤害预测准确性,但会让“是谁在起作用”的解读更困难。
  • 更多输入不保证更好预测:在留出数据上将每个候选预测变量与基线进行对比评估。某些在样本内看似有信息量的特征,在样本外只会带来噪声。
  • 季节性需要季节项:如果序列存在稳定的季节性模式,如每年 12 月的月度销量峰值,那么应使用带季节阶数的 SARIMAX。仅用 ARIMAX 无法捕捉。
  • 不能据此建立因果:再强调一次:ARIMAX 是预测框架,而非因果推断方法。不要仅凭系数符号在没有额外分析的情况下做因果判断。

结论

当外部因素确实会影响目标,且在预测时您能提供它们的未来值,ARIMAX 才名副其实。它是 ARIMA 的自然扩展,而非替代。如果您的序列表现良好,且没有可靠的预测变量,纯 ARIMA 通常是更好的起点。添加变量会让人感觉在“进步”,但有时并非如此。

工作流归结为四件事要做好:

  1. 正确对齐预测变量;
  2. 评估前检查是否存在泄漏;
  3. 在真正留出的数据上验证;以及
  4. 始终与简单基线进行比较。

一个仅略微优于天真预测的 ARIMAX 模型并不比天真预测更好,它只是更昂贵。

如果您想更系统地打好时间序列基础,我们的 Time Series Analysis in Python 课程详细讲解了 ARIMA、平稳性与诊断。关于 statsmodels,我们的 Introduction to Regression with statsmodels in Python 课程将帮助您建立解读模型摘要与检查残差所需的统计直觉。


Vinod Chugani's photo
Author
Vinod Chugani
LinkedIn

Vinod Chugani 的职业生涯始于东京,曾任摩根大通最年轻的对冲基金销售台负责人,随后在雷曼兄弟创下个人销售纪录,之后又打造了覆盖 30 个国家的电子分销业务,营收突破 1 亿新元,随后转向数据领域。他毕业于杜克大学经济学专业,亦为 NYC Data Science Academy 校友,并在 100 多名申请者中成为Hugo Bowne-Anderson 在 Maven 开设的 “Building AI Applications” 课程的三位奖学金获得者之一。目前,他为 DataCamp、KDnuggets、Machine Learning Mastery 和 Statology 撰稿,内容涵盖从统计学到代理式 AI 等主题,并在 NYC Data Science Academy 指导数据从业者,已完成超过 1,000 场一对一辅导。

 

FAQs

ARIMAX 与 ARIMA 有何区别?

ARIMA 仅使用目标序列自身的历史数值和过去的预测误差来做预测。ARIMAX 在此基础上引入外生变量——诸如气温、促销或利率等外部输入——它们被认为会影响目标。如果这些外部因素确实驱动了序列中的波动,且您能提供它们的未来值,ARIMAX 通常会比仅用 ARIMA 产生更好的预测。

ARIMAX 与 SARIMAX 有何不同?

ARIMAX 能处理外部变量,但不包含季节性项。SARIMAX 在 ARIMAX 基础上加入季节性的 AR、差分与 MA 项,因此当序列存在重复的季节性结构时应选择 SARIMAX。在 Python 的 statsmodels 中,ARIMAX 通常通过 SARIMAX() 实现,并将季节阶数设为 (0, 0, 0, 0)。在该配置下,两者在功能上等同。

使用 ARIMAX 进行预测时,是否需要提供外生变量的未来值?

是的——这是最重要的实际约束之一。在生成训练期之外的预测时,您必须在每个未来时间点为每个外生变量提供取值。对于促销标记或节假日指示器,这通常很直接。对于气温或大宗商品价格等变量,您需要使用预测值或合理假设,这会引入额外的不确定性。

如何为 ARIMAX 模型选择 p、d、q?

先查看(差分后的)目标序列的 ACF 与 PACF 图。PACF 在滞后 1 处显著且 ACF 衰减通常提示 AR(1);相反的模式提示 MA(1)。利用领域知识与 ADF 检验确定 d。随后在训练数据上用 AIC 或 BIC 比较少量候选 (p, d, q) 组合。避免在此选择步骤中使用测试集——测试集只应用于最终评估。

ARIMAX 模型中外生变量的系数意味着什么?

该系数表示在考虑自回归结构之后,预测变量每增加 1 个单位与目标序列“水平”变化之间的估计关联。在 statsmodels 中,即便 d=1 也成立,因为差分是施加在误差过程中,而非回归方程本身(即带 ARIMA 误差的回归表述)。一些其他包采用传递函数表述,此时 d=1 会让系数反映对“变化量”的影响而非“水平”,因此请查阅您所用工具的文档。当预测变量的量纲不同或彼此相关时,解读也会变得棘手;若需要比较系数,值得对输入做标准化。

如何检测并处理外生预测变量的多重共线性?

在拟合前计算每个预测变量的方差膨胀因子(VIF)。超过 10 表示存在严重共线性。如果发现问题,尝试移除最缺乏理论支撑的预测变量,或将相关变量合并为单一复合变量。高共线性不一定会损害预测准确性,但会让单个系数不可靠且难以解读。

如何评估 ARIMAX 是否真的带来了价值?

始终与简单基线比较——天真预测(用前一期数值)是很好的起点。如果 ARIMAX 在留出测试数据上未胜出,就不配得上它的复杂性。MAE 与 RMSE 都是合理指标;MAE 更易向业务方解释。务必在未参与参数选择的真正测试集上进行对比。

何时应使用 SARIMAX 而非 ARIMAX?

当序列呈现稳定的季节性模式时使用 SARIMAX——例如 12 月峰值的月度销量、周一高峰的网站周流量等。SARIMAX 增加了 ARIMAX 所不具备的季节性 AR、差分与 MA 组件。由于 Python 的 statsmodels 本就通过 SARIMAX() 来实现 ARIMAX,因此实操问题只是要不要设置非零的季节阶数。如果在拟合 ARIMAX 后,残差在季节性滞后处仍显示显著自相关,那就是应加入季节项的信号。

主题
数据科学

与 DataCamp 一起学习

课程

R 中的预测

5 小时
52.8K
学习如何使用 R 中的时间序列预测来预测未来,包括 ARIMA 模型和指数平滑方法。
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多