别再只调包了!用Python的statsmodels从时序图到预测,手把手复现一个ARIMA模型

发布时间:2026/5/24 17:52:23

别再只调包了!用Python的statsmodels从时序图到预测,手把手复现一个ARIMA模型 从时序图到预测用Python手把手构建ARIMA模型的完整思维框架当你第一次接触时间序列预测时可能被各种统计术语和数学公式吓到。但别担心我们今天要做的不是数学推导而是通过Python代码和实际案例带你理解ARIMA模型背后的完整逻辑链条。这不是简单的导入库-拟合数据-得到预测的流程而是一个数据科学家处理时间序列问题的完整思维框架。1. 理解时间序列分析的基础概念时间序列分析的核心目标是发现数据中的模式并利用这些模式预测未来。想象你是一名零售店经理手上有过去三年的月销售数据。你可能会观察到趋势销售额每年增长5%季节性每年12月销售额激增随机波动某些月份出现无法解释的波动ARIMA模型就是用来捕捉这些模式的工具之一。它由三个部分组成AR (自回归)当前值与过去值的关系I (差分)使序列平稳所需的差分次数MA (移动平均)当前值与过去误差的关系在实际应用中我们通常遵循这样的流程原始序列 → 平稳性检验 → 差分处理 → 模型定阶 → 参数估计 → 模型检验 → 预测2. 数据准备与初步观察让我们使用一个真实的零售销售数据集来演示。首先加载必要的库import pandas as pd import numpy as np import matplotlib.pyplot as plt import statsmodels.api as sm from statsmodels.tsa.stattools import adfuller from statsmodels.graphics.tsaplots import plot_acf, plot_pacf plt.style.use(seaborn)加载并观察数据# 假设数据存储在sales.csv中 data pd.read_csv(sales.csv, parse_dates[date], index_coldate) print(data.head()) # 绘制原始序列 data.plot(figsize(12,6), titleMonthly Retail Sales) plt.ylabel(Sales Volume) plt.show()关键观察点数据是否有明显的上升/下降趋势是否存在周期性波动波动幅度是否随时间变化3. 平稳性检验与处理平稳性是ARIMA模型的核心假设。一个平稳的时间序列意味着其统计特性如均值、方差不随时间变化。我们通过两种方式检验平稳性3.1 视觉检验# 绘制原始序列和差分序列 fig, axes plt.subplots(3,1, figsize(12,12)) data.plot(axaxes[0], titleOriginal Series) data.diff().plot(axaxes[1], titleFirst Difference) data.diff().diff().plot(axaxes[2], titleSecond Difference) plt.tight_layout() plt.show()3.2 ADF单位根检验def test_stationarity(timeseries): # 执行ADF检验 result adfuller(timeseries.dropna()) print(ADF Statistic: %f % result[0]) print(p-value: %f % result[1]) print(Critical Values:) for key, value in result[4].items(): print(\t%s: %.3f % (key, value)) # 判断是否平稳 if result[1] 0.05: print(拒绝原假设序列平稳) else: print(不能拒绝原假设序列非平稳) test_stationarity(data[sales])结果解读如果p值0.05需要进行差分处理通常1-2次差分就能达到平稳过度差分会导致信息损失4. 模型识别与定阶确定差分次数d后我们需要确定AR(p)和MA(q)的阶数。这通过观察ACF和PACF图实现# 绘制ACF和PACF图 fig, (ax1, ax2) plt.subplots(2,1, figsize(12,8)) plot_acf(data.diff().dropna(), axax1, lags20) plot_pacf(data.diff().dropna(), axax2, lags20) plt.tight_layout() plt.show()识别规则模式AR(p)MA(q)ACF拖尾q阶截尾PACFp阶截尾拖尾在实际操作中我们通常会尝试多个(p,d,q)组合然后选择信息准则最优的模型# 尝试不同模型 model1 sm.tsa.ARIMA(data, order(1,1,0)).fit() # AR(1) model2 sm.tsa.ARIMA(data, order(0,1,1)).fit() # MA(1) model3 sm.tsa.ARIMA(data, order(1,1,1)).fit() # ARMA(1,1) # 比较模型 print(fAR(1) AIC:{model1.aic:.2f} BIC:{model1.bic:.2f}) print(fMA(1) AIC:{model2.aic:.2f} BIC:{model2.bic:.2f}) print(fARMA(1,1) AIC:{model3.aic:.2f} BIC:{model3.bic:.2f})5. 模型诊断与验证选择最优模型后我们需要验证残差是否为白噪声# 残差诊断 residuals model2.resid fig, (ax1, ax2) plt.subplots(2,1, figsize(12,8)) plot_acf(residuals, axax1, lags20) plot_pacf(residuals, axax2, lags20) plt.tight_layout() plt.show() # Ljung-Box检验 lb_test sm.stats.acorr_ljungbox(residuals, lags[10]) print(fLjung-Box检验p值: {lb_test[1][0]:.4f})理想结果残差的ACF/PACF没有显著相关性Ljung-Box检验p值0.05QQ图显示残差近似正态分布6. 预测与结果可视化最后我们可以用训练好的模型进行预测# 未来12个月的预测 forecast model2.get_forecast(steps12) forecast_mean forecast.predicted_mean conf_int forecast.conf_int() # 绘制结果 plt.figure(figsize(12,6)) data.plot(labelObserved) forecast_mean.plot(labelForecast, colorr) plt.fill_between(conf_int.index, conf_int.iloc[:,0], conf_int.iloc[:,1], colorpink, alpha0.3) plt.title(Sales Forecast with 95% Confidence Interval) plt.legend() plt.show()预测注意事项ARIMA对短期预测效果较好长期预测误差会累积增大对于季节性数据考虑SARIMA模型7. 实际应用中的经验分享在实际项目中我发现几个常见问题值得注意数据频率选择日数据可能有周模式月数据更适合观察长期趋势高频数据需要处理节假日效应异常值处理# 识别和处理异常值 from statsmodels.tsa.statespace.tools import cfa_filter filtered cfa_filter(data, freq12)模型更新策略固定窗口滚动训练增量更新模型参数定期重新评估模型性能多模型比较from pmdarima import auto_arima model auto_arima(data, seasonalTrue, m12)记住ARIMA不是万能的。当数据有以下特征时可能需要其他方法存在外部变量影响具有复杂的多重季节性呈现非线性模式

相关新闻