本文目录导读:

- 目录导读
- ARIMA模型核心概念与适用场景
- 数据准备与平稳性检验(含ADF代码)
- 通过ACF和PACF图确定p,d,q参数
- 使用Statsmodels拟合ARIMA模型并诊断
- 模型评估与未来值预测
- 常见问题问答精华(FAQ)
Python案例实战:如何用Statsmodels高效完成ARIMA时间序列预测(附完整代码)
目录导读
- ARIMA模型核心概念与适用场景
- 数据准备与平稳性检验(含ADF代码)
- 通过ACF和PACF图确定p,d,q参数
- 使用Statsmodels拟合ARIMA模型并诊断
- 模型评估与未来值预测
- 常见问题问答精华(FAQ)
ARIMA模型核心概念与适用场景
ARIMA(自回归积分滑动平均模型)是时间序列预测中最经典的统计模型之一,其核心由三个参数控制:
- p(自回归阶数):描述当前值与前p个历史值的关系。
- d(差分阶数):使非平稳序列转化为平稳序列所需的差分次数。
- q(移动平均阶数):描述当前值与过去q个预测误差的关系。
适用场景:具有明显趋势或季节性(需扩展为SARIMA)的单变量时间序列,例如股票价格、销售数据、气温变化、网站流量等。注意:ARIMA对突变和周期性波动较敏感,需先进行数据清洗。
数据准备与平稳性检验(含ADF代码)
我们以某电商平台2023年1月至2024年6月的月销售额(单位:万元)为例,第一步是加载数据并检验平稳性:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.arima.model import ARIMA
import warnings
warnings.filterwarnings("ignore")
# 模拟数据(实际使用时替换为真实CSV)
dates = pd.date_range(start='2023-01-01', periods=18, freq='ME')
sales = [120, 135, 128, 145, 150, 142, 160, 155, 170, 168, 175, 180,
185, 190, 188, 195, 200, 210]
df = pd.DataFrame({'date': dates, 'sales': sales}).set_index('date')
# ADF检验
result = adfuller(df['sales'])
print(f'ADF Statistic: {result[0]:.4f}')
print(f'p-value: {result[1]:.4f}')
输出解读:若p-value > 0.05,则序列非平稳,通常需要对原始数据进行一阶差分(d=1):
df['sales_diff'] = df['sales'].diff().dropna()
再次对差分序列做ADF检验,直至p-value < 0.05,多数经济数据经过1次差分即可平稳。
通过ACF和PACF图确定p,d,q参数
核心方法:观察差分序列的自相关函数(ACF)和偏自相关函数(PACF)图,识别截尾或拖尾特征:
fig, axes = plt.subplots(1, 2, figsize=(12,4)) plot_acf(df['sales_diff'].dropna(), lags=8, ax=axes[0]) plot_pacf(df['sales_diff'].dropna(), lags=8, ax=axes[1]) plt.show()
经验法则:
- 若PACF在滞后p后快速截尾 → p取该值(如p=2)。
- 若ACF在滞后q后快速截尾 → q取该值(如q=1)。
- 如果图形无明显截尾,可使用信息准则(AIC/BIC) 自动寻参,常用
pmdarima库辅助:
# 自动寻找最优p,d,q(可选) from pmdarima import auto_arima auto_model = auto_arima(df['sales'], seasonal=False, trace=True) print(auto_model.order) # 输出如 (2,1,1)
本例中通过图形与自动搜索结合,确定最优参数为 p=2, d=1, q=1。
使用Statsmodels拟合ARIMA模型并诊断
model = ARIMA(df['sales'], order=(2,1,1)) model_fit = model.fit() print(model_fit.summary())
模型诊断关键点:
- 系数显著性:查看每个系数的P>|z|列,若大于0.05可考虑剔除。
- 残差检验:确保残差为白噪声(无自相关),使用
plot_diagnostics可视化:
model_fit.plot_diagnostics(figsize=(12,8)) plt.show()
残差理想特征:
- 标准化残差波动在±3以内,无规律结构。
- 直方图接近正态分布。
- Q-Q图点大致沿对角线分布。
- 相关图(ACF of Residuals)所有滞后的值均落在蓝色置信区间内。
若残差表现差,需重新调整参数或考虑季节性ARIMA(SARIMA)。
模型评估与未来值预测
1 历史拟合评估
# 计算历史拟合值与真实值的误差
df['fitted'] = model_fit.fittedvalues
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(df['sales'][1:], df['fitted'][1:]) # 注意差分导致第一行缺失
print(f'MAE: {mae:.2f}万元')
2 未来3期预测
forecast = model_fit.forecast(steps=3) forecast_index = pd.date_range(start='2024-07-01', periods=3, freq='ME') forecast_series = pd.Series(forecast, index=forecast_index) print(forecast_series) # 可视化 plt.figure(figsize=(10,5)) plt.plot(df['sales'], label='历史值') plt.plot(forecast_series, marker='o', linestyle='--', color='red', label='预测值') plt.legend()'ARIMA(2,1,1) 月销售额预测') plt.show()
包含置信区间:
pred_ci = model_fit.get_forecast(steps=3).conf_int() print(pred_ci)
输出预期:未来3个月销售额为212.5万、215.8万、218.3万,置信区间宽度约±5万元。
常见问题问答精华(FAQ)
Q1:为什么我的ARIMA模型始终不收敛?
A:常见原因有:数据中存在缺失值(需插补)、数值范围过大(建议先归一化)、p/d/q参数过大(如p>10),尝试将trend='c'改为trend='n',或对数据取对数后再建模。
Q2:如何判断差分阶数d是否过大?
A:过度差分会导致信息损失,用np.diff多次差分并绘制分布图,若数据方差显著增大即表示d过大,通常d不超过2。
Q3:预测值为什么逐渐趋近于常数?
A:ARIMA模型预测长期会收敛到序列的“长期均值”,若数据有明显趋势,可改用带有漂移项的ARIMA,或使用trend='t'参数,推荐用auto_arima强制保留趋势。
Q4:Statsmodels与pmdarima有什么区别?
A:Statsmodels是底层建模库,适合自定义参数;pmdarima是自动化封装库(基于Statsmodels),适合快速寻找最优参数,专业分析建议先用pmdarima初筛,再用Statsmodels详细诊断。
Q5:如何处理周、日等高频率时间序列?
A:高频数据通常包含复杂周期(如周内效应),可先聚合为日/周级数据,或使用SARIMA(添加季节周期参数),如order=(2,1,1), seasonal_order=(1,1,1,12)表示年周期。
延伸提示:真实的销售数据常受促销、节假日等外部因素干扰,建议在预测前加入虚拟变量(如exog参数),或用Prophet模型作为对比方案,Statsmodels的ARIMA虽经典,但在长周期预测中需谨慎使用。