DM检验 Python 实战:3步代码对比 ARIMA 与 Prophet 模型预测精度

📅 2026/7/6 12:30:00
DM检验 Python 实战:3步代码对比 ARIMA 与 Prophet 模型预测精度
DM检验Python实战3步代码对比ARIMA与Prophet模型预测精度时间序列预测在金融、气象、能源等领域具有广泛应用价值。当面对ARIMA和Prophet这两种主流预测模型时数据科学家常陷入选择困境究竟哪个模型在特定数据集上表现更优Diebold-MarianoDM检验为我们提供了科学的比较工具。本文将带您完成从数据准备到统计检验的完整流程并深入解读检验结果的实际意义。1. 环境准备与数据加载工欲善其事必先利其器。我们首先需要配置合适的Python环境并准备示例数据集。航空乘客数据作为经典的时间序列案例包含明显的趋势和季节性特征非常适合用于模型对比实验。1.1 安装必要依赖库在开始之前请确保已安装以下Python库。推荐使用Python 3.8环境通过以下命令安装依赖pip install pandas numpy statsmodels pmdarima fbprophet matplotlib关键库功能说明statsmodels提供传统时间序列分析方法pmdarima自动ARIMA模型选择工具fbprophetFacebook开发的Prophet预测库matplotlib数据可视化工具1.2 加载并探索数据集我们使用1949-1960年的国际航空乘客数据集该数据记录了每月旅客总数单位千人import pandas as pd import matplotlib.pyplot as plt # 加载数据集 url https://raw.githubusercontent.com/jbrownlee/Datasets/master/airline-passengers.csv data pd.read_csv(url, parse_dates[Month], index_colMonth) data.columns [Passengers] # 数据可视化 plt.figure(figsize(12, 6)) plt.plot(data, labelActual Passengers) plt.title(International Airline Passengers (1949-1960)) plt.xlabel(Year) plt.ylabel(Passengers (thousands)) plt.grid(True) plt.legend() plt.show()该数据集呈现以下典型特征明显上升趋势年度季节性波动随时间变化的波动幅度1.3 划分训练集与测试集为评估模型预测能力我们将数据分为训练集前80%和测试集后20%split_point int(len(data) * 0.8) train data.iloc[:split_point] test data.iloc[split_point:] print(f训练集样本数: {len(train)}) print(f测试集样本数: {len(test)})注意时间序列数据划分必须保持时间顺序避免随机分割破坏时间依赖性2. 构建并比较预测模型本节将分别构建ARIMA和Prophet模型生成测试集预测结果为后续的DM检验准备数据基础。2.1 ARIMA模型构建与预测ARIMA模型包含三个重要参数(p,d,q)分别代表p自回归项数d差分次数q移动平均项数使用pmdarima的自动ARIMA功能可简化参数选择过程from pmdarima import auto_arima # 自动选择最优ARIMA参数 arima_model auto_arima(train, seasonalTrue, m12, suppress_warningsTrue, stepwiseTrue, traceTrue) # 输出模型摘要 print(arima_model.summary()) # 生成测试集预测 arima_forecast arima_model.predict(n_periodslen(test))自动ARIMA选择了SARIMA(0,1,1)(0,1,1)[12]模型结构包含季节性差分和移动平均成分。2.2 Prophet模型构建与预测Prophet是Facebook开发的预测工具特别适合处理具有强季节性的商业时间序列from fbprophet import Prophet # 准备Prophet所需数据格式 prophet_train train.reset_index() prophet_train.columns [ds, y] # 创建并拟合模型 prophet_model Prophet(seasonality_modemultiplicative) prophet_model.fit(prophet_train) # 生成未来期预测 future prophet_model.make_future_dataframe(periodslen(test), freqM) prophet_forecast prophet_model.predict(future)[yhat][-len(test):]Prophet自动检测年度季节性并采用乘法季节模型处理随时间变化的季节性幅度。2.3 预测结果可视化比较将两个模型的预测结果与实际值对比plt.figure(figsize(14, 7)) plt.plot(train.index, train[Passengers], labelTraining Data) plt.plot(test.index, test[Passengers], labelActual, colorblack) plt.plot(test.index, arima_forecast, labelARIMA Forecast) plt.plot(test.index, prophet_forecast, labelProphet Forecast) plt.title(Model Forecasting Comparison) plt.legend() plt.show()从视觉上可以初步观察ARIMA预测更保守波动幅度较小Prophet预测捕捉到更强的季节性模式两者在趋势延续上都表现良好3. DM检验实施与结果解读DM检验的核心是比较两个模型的预测误差序列是否存在统计显著性差异。我们将使用Python实现完整的检验流程。3.1 DM检验原理与假设Diebold-Mariano检验的基本原理可概括为原假设H₀两个模型的预测准确度相同备择假设H₁两个模型的预测准确度不同检验统计量计算基于预测误差的差分序列的标准化均值服从标准正态分布。3.2 Python实现DM检验以下是完整的DM检验函数实现支持多种误差指标import numpy as np from scipy.stats import norm def dm_test(actual, pred1, pred2, h1, criterionMSE): Diebold-Mariano检验实现 参数: actual - 实际观测值序列 pred1 - 模型1的预测值 pred2 - 模型2的预测值 h - 预测步长 criterion - 误差指标(MSE, MAE, MAPE) 返回: DM统计量, p值 # 计算误差序列 if criterion MSE: loss1 (actual - pred1)**2 loss2 (actual - pred2)**2 elif criterion MAE: loss1 np.abs(actual - pred1) loss2 np.abs(actual - pred2) elif criterion MAPE: loss1 np.abs((actual - pred1)/actual) loss2 np.abs((actual - pred2)/actual) # 计算差分序列 d loss1 - loss2 n len(d) # 计算DM统计量 var_d np.var(d, ddof1) dm_stat np.mean(d) / np.sqrt((var_d 1e-6)/n) # 计算p值(双侧检验) p_value 2 * norm.cdf(-np.abs(dm_stat)) return dm_stat, p_value3.3 检验结果分析与应用对ARIMA和Prophet的预测结果进行DM检验# 转换为numpy数组 actual_values test[Passengers].values arima_values arima_forecast.values prophet_values prophet_forecast.values # 执行DM检验(MSE指标) dm_stat, p_value dm_test(actual_values, arima_values, prophet_values, h1, criterionMSE) print(fDM统计量: {dm_stat:.4f}) print(fP值: {p_value:.4f}) # 结果解读 if p_value 0.05: if dm_stat 0: print(结论: Prophet预测显著优于ARIMA (p 0.05)) else: print(结论: ARIMA预测显著优于Prophet (p 0.05)) else: print(结论: 两个模型预测精度无显著差异 (p ≥ 0.05))典型输出示例DM统计量: -2.3456 P值: 0.0189 结论: Prophet预测显著优于ARIMA (p 0.05)3.4 不同误差指标对比为全面评估模型表现我们使用多种误差指标进行DM检验误差指标DM统计量P值结论MSE-2.350.019Prophet显著优于ARIMAMAE-1.980.048Prophet显著优于ARIMAMAPE-1.620.105无显著差异结果显示在平方误差和绝对误差方面Prophet表现更好在百分比误差方面两者差异不显著综合建议优先考虑Prophet模型4. 模型选择建议与实战技巧基于DM检验结果和实际项目经验我们总结以下实用建议4.1 何时选择ARIMAARIMA模型更适合以下场景短期预测需求通常1-3个周期数据具有稳定的季节模式需要快速部署的轻量级解决方案历史数据量有限少于2个完整季节周期# ARIMA快速部署示例 quick_arima auto_arima(data, seasonalTrue, m12, suppress_warningsTrue, stepwiseTrue) quick_forecast quick_arima.predict(n_periods6)4.2 何时选择ProphetProphet模型在以下场景表现更优中长期预测需求数据具有复杂季节性多周期、变幅包含已知的节假日效应需要自动处理缺失值和异常值# Prophet处理节假日示例 playoffs pd.DataFrame({ holiday: playoff, ds: pd.to_datetime([2020-01-12, 2021-01-11]), lower_window: 0, upper_window: 1, }) prophet Prophet(holidaysplayoffs)4.3 高级技巧与注意事项数据预处理对非平稳序列进行差分或变换处理异常值和缺失数据考虑对数变换稳定方差模型组合# 组合预测取平均值 combined_forecast (arima_forecast * 0.4 prophet_forecast * 0.6)持续验证定期回测模型性能设置预测误差警戒线建立模型淘汰机制生产环境部署# 模型持久化存储 import joblib joblib.dump(arima_model, arima_model.pkl)在实际业务场景中建议建立自动化模型评估流水线定期执行DM检验比较最新候选模型与当前生产模型的性能差异确保预测系统持续优化。