Python案例如何用Statsmodels做ARIMA预测

wen python案例 1

本文目录导读:

Python案例如何用Statsmodels做ARIMA预测

  1. 目录导读
  2. ARIMA模型核心概念与适用场景
  3. 数据准备与平稳性检验(含ADF代码)
  4. 通过ACF和PACF图确定p,d,q参数
  5. 使用Statsmodels拟合ARIMA模型并诊断
  6. 模型评估与未来值预测
  7. 常见问题问答精华(FAQ)

Python案例实战:如何用Statsmodels高效完成ARIMA时间序列预测(附完整代码)

目录导读

  1. ARIMA模型核心概念与适用场景
  2. 数据准备与平稳性检验(含ADF代码)
  3. 通过ACF和PACF图确定p,d,q参数
  4. 使用Statsmodels拟合ARIMA模型并诊断
  5. 模型评估与未来值预测
  6. 常见问题问答精华(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虽经典,但在长周期预测中需谨慎使用。

抱歉,评论功能暂时关闭!