ARIMA 模型:非平稳时间序列预测的 “瑞士军刀”

一、从 ARMA 到 ARIMA:为什么需要 “差分”?

在之前的文章中,我们学习了 ARMA 模型如何通过历史观测值和误差项预测未来。但 ARMA 有个致命短板——它只能处理平稳时间序列

什么是平稳序列?简单说,就是序列的均值、方差不随时间变化。但现实中,多数时间序列都带有趋势或季节性(如股票价格、GDP 增长、月度销量),这些序列明显非平稳,直接用 ARMA 会导致严重偏差。

举个例子:预测某公司的销售额(逐年增长),若忽略增长趋势,模型会把 “增长” 误判为随机波动,预测结果将严重滞后于实际值。

ARIMA 模型的核心创新:通过差分操作消除趋势,将非平稳序列转化为平稳序列,再用 ARMA 建模。这就像给模型装了个 “趋势过滤器”,让它专注于捕捉数据的本质规律。

二、ARIMA 的三要素:(p, d, q)

ARIMA 模型由三个参数定义:ARIMA(p, d, q),每个参数都有明确的物理意义:

  • p:自回归阶数(AR 部分),表示使用过去 p 期的观测值;
  • d:差分阶数,表示需要对原始数据进行 d 次差分以达到平稳;
  • q:移动平均阶数(MA 部分),表示使用过去 q 期的误差项。

差分操作详解

差分是 ARIMA 的灵魂,它通过计算相邻数据点的差值来消除趋势。例如:

  • 一阶差分Δxt=xt−xt−1\Delta x_t = x_t - x_{t-1}Δxt=xtxt1(消除线性趋势)
  • 二阶差分Δ2xt=Δxt−Δxt−1\Delta^2 x_t = \Delta x_t - \Delta x_{t-1}Δ2xt=ΔxtΔxt1(消除二次趋势)

直观理解:如果原始数据是 “销售额”,一阶差分后就变成了 “销售额的增长量”,而增长量通常比原始值更平稳。

三、ARIMA 模型的数学原理

核心公式

ARIMA(p, d, q) 的完整表达式可以拆分为两部分:

  1. 差分过程:将原始序列 xtx_txt 转换为平稳序列 yty_tyt
    yt=Δdxt y_t = \Delta^d x_t yt=Δdxt

  2. ARMA 建模:对平稳序列 yty_tyt 应用 ARMA(p, q)
    yt=ϕ1yt−1+⋯+ϕpyt−p+θ1εt−1+⋯+θqεt−q+εt y_t = \phi_1 y_{t-1} + \cdots + \phi_p y_{t-p} + \theta_1 \varepsilon_{t-1} + \cdots + \theta_q \varepsilon_{t-q} + \varepsilon_t yt=ϕ1yt1++ϕpytp+θ1εt1++θqεtq+εt

其中,ϕi\phi_iϕi 是 AR 系数,θj\theta_jθj 是 MA 系数,εt\varepsilon_tεt 是白噪声误差。

参数估计方法

ARIMA 模型的参数估计分为两步:

  1. 确定 d:通过 ADF 检验(单位根检验)判断序列是否平稳,逐步增加差分次数直到平稳;
  2. 确定 p 和 q:对差分后的平稳序列,使用 ACF/PACF 图或信息准则(AIC/BIC)选择最优阶数。

四、ARIMA 建模实战:Python 实现

下面通过一个完整案例,展示如何使用 ARIMA 模型预测带趋势的时间序列数据:

案例:预测公司季度营收(带增长趋势)

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 设置随机种子,确保结果可复现
np.random.seed(42)

# 1. 生成带趋势的季度营收数据(2018-2022年)
dates = pd.date_range(start='2018-01-01', periods=20, freq='Q')
trend = np.linspace(100, 300, 20)  # 线性增长趋势
noise = np.random.normal(0, 20, 20)  # 随机噪声
revenue = trend + noise  # 季度营收 = 趋势 + 噪声

# 创建DataFrame
df = pd.DataFrame({'revenue': revenue}, index=dates)

# 2. 可视化原始数据
plt.figure(figsize=(12, 8))
plt.subplot(2, 2, 1)
plt.plot(df.index, df['revenue'], color='blue', linewidth=2)
plt.title('原始季度营收数据(非平稳)', fontsize=14)
plt.grid(True)

# 3. 平稳性检验(ADF检验)
def adf_test(series):
    result = adfuller(series)
    print(f'ADF Statistic: {result[0]}')
    print(f'p-value: {result[1]}')
    print('Critical Values:')
    for key, value in result[4].items():
        print(f'\t{key}: {value}')
    if result[1] <= 0.05:
        print("序列平稳(拒绝原假设)")
    else:
        print("序列非平稳(接受原假设)")

print("原始数据的ADF检验:")
adf_test(df['revenue'])

# 4. 一阶差分并检验平稳性
df['diff1'] = df['revenue'].diff().dropna()
plt.subplot(2, 2, 2)
plt.plot(df.index[1:], df['diff1'][1:], color='green', linewidth=2)
plt.title('一阶差分后数据(平稳)', fontsize=14)
plt.grid(True)

print("\n一阶差分后的ADF检验:")
adf_test(df['diff1'].dropna())

# 5. 绘制ACF和PACF图(确定p和q)
plt.subplot(2, 2, 3)
plot_acf(df['diff1'].dropna(), lags=10, ax=plt.gca())
plt.title('差分后序列的ACF图', fontsize=14)

plt.subplot(2, 2, 4)
plot_pacf(df['diff1'].dropna(), lags=10, ax=plt.gca())
plt.title('差分后序列的PACF图', fontsize=14)

plt.tight_layout()
plt.show()

# 6. 拟合ARIMA(2,1,2)模型
model = ARIMA(df['revenue'], order=(2, 1, 2))  # p=2, d=1, q=2
model_fit = model.fit()

# 7. 预测未来8个季度的营收
forecast_steps = 8
forecast = model_fit.forecast(steps=forecast_steps)
forecast_index = pd.date_range(start=df.index[-1] + pd.DateOffset(months=3), periods=forecast_steps, freq='Q')

# 8. 可视化预测结果
plt.figure(figsize=(12, 6))
plt.plot(df.index, df['revenue'], label='历史营收', color='blue', linewidth=2)
plt.plot(forecast_index, forecast, label='预测营收', color='red', linestyle='--', linewidth=2)
plt.title('季度营收预测(ARIMA模型)', fontsize=14)
plt.xlabel('日期')
plt.ylabel('营收(万元)')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

五、ARIMA 建模全流程解析

1. 数据生成与探索

我们创建了一个带线性增长趋势的季度营收数据,从图中可以明显看出均值随时间增加,属于非平稳序列。

2. 平稳性检验

通过 ADF 检验判断序列是否平稳:

  • 原假设:序列非平稳
  • 若 p-value > 0.05,则接受原假设,序列非平稳

原始数据的 ADF 检验 p-value ≈ 0.99,说明非平稳,需要差分。

3. 差分转换

对原始数据进行一阶差分后,再次进行 ADF 检验,此时 p-value ≈ 0.0001,说明已平稳,故 d=1。

4. 确定 p 和 q

通过 ACF/PACF 图判断阶数:

  • ACF 图:在滞后 2 阶后截尾 → q=2
  • PACF 图:在滞后 2 阶后截尾 → p=2

因此,选择 ARIMA(2, 1, 2) 模型。

5. 模型拟合与预测

使用选定的参数拟合模型,并预测未来 8 个季度的营收。从预测结果可以看到,模型成功捕捉了原始数据的增长趋势,并给出了合理的预测区间。

六、ARIMA 模型的优缺点与适用场景

优点

  1. 适用性广:能处理各种趋势的非平稳序列(线性、非线性)
  2. 理论成熟:有严格的数学基础和统计检验方法
  3. 可解释性强:参数具有明确的物理意义
  4. 短期预测精准:在处理 1-12 期预测时表现优异

缺点

  1. 不适合长期预测:超过一定期限后,预测值会收敛到均值
  2. 无法处理季节性:对季节性波动大的数据效果不佳(需用 SARIMA)
  3. 参数调优复杂:需要反复尝试不同的 (p, d, q) 组合

适用场景

  • 具有趋势但无明显季节性的数据(如 GDP、人口增长)
  • 短期预测需求(如未来 1 年的销售额)
  • 需要明确解释变量影响的场景

七、ARIMA 的进阶技巧与注意事项

1. 差分次数 d 的选择

  • 多数情况下,d=0 或 1 即可
  • 若序列有二次趋势(如指数增长),可能需要 d=2
  • 极少需要 d≥3,因为过度差分会导致信息丢失

2. 自动定阶工具

除了手动观察 ACF/PACF,还可以使用自动定阶函数:

import pmdarima as pm

# 自动寻找最优(p,d,q)参数
model = pm.auto_arima(df['revenue'], 
                      start_p=0, start_q=0,
                      max_p=5, max_q=5,
                      d=None,              # 自动确定差分阶数
                      seasonal=False,      # 暂不考虑季节性
                      trace=True)          # 打印搜索过程

3. 模型评估指标

常用指标包括:

  • AIC/BIC:越小越好
  • MAE/MSE/RMSE:衡量预测误差
  • Ljung-Box 检验:检验残差是否为白噪声

八、总结与展望

ARIMA 模型通过 “差分 + ARMA” 的组合,成功解决了非平稳时间序列的预测难题。其核心在于通过差分消除趋势,让模型专注于捕捉数据的本质波动规律。

但 ARIMA 仍有局限——它无法直接处理季节性数据。在下一篇文章中,我们将学习 SARIMA 模型(季节性 ARIMA),看看如何同时处理趋势和季节性,敬请期待!

如果本文对你有帮助,欢迎分享给更多需要的朋友~ 有任何疑问或建议,欢迎在评论区留言交流!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值