 模型实战:Python statsmodels 库实现销售预测,RMSE 降低 15%)
ARIMA(p,d,q) 模型实战Python statsmodels 库实现销售预测RMSE 降低 15%当销售总监问下个季度能卖多少时时间序列预测就是数据分析师的魔法水晶球。在众多预测工具中ARIMA模型以其数学严谨性和业务解释性成为销售预测的经典选择。本文将手把手带你用Python的statsmodels库从数据清洗到模型部署完整实现一个可落地的销售预测方案。1. 环境准备与数据探索工欲善其事必先利其器。我们先配置好Python环境# 基础库 import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline # 时间序列专用 from statsmodels.tsa.stattools import adfuller # ADF检验 from statsmodels.graphics.tsaplots import plot_acf, plot_pacf # ACF/PACF from statsmodels.tsa.arima.model import ARIMA # ARIMA模型 from sklearn.metrics import mean_squared_error # 评估指标假设我们有一份2018-2022年的月度销售数据sales.csv字段包括date: 日期YYYY-MM-DDsales: 销售额万元先进行基础探索df pd.read_csv(sales.csv, parse_dates[date]) df.set_index(date, inplaceTrue) print(df.head()) # 绘制原始序列 plt.figure(figsize(12,6)) plt.plot(df, labelRaw Data) plt.title(Monthly Sales Trend) plt.legend()常见的数据问题及处理方法问题类型检测方法解决方案缺失值df.isnull().sum()线性插值或前向填充异常值箱线图观察Winsorize处理或中位数替换周期性分解季节成分季节差分或外部变量趋势性ADF检验常规差分或对数变换2. 平稳化处理与参数确定ARIMA建模的前提是序列平稳。我们先用ADF检验验证def adf_test(series): result adfuller(series) print(ADF Statistic:, result[0]) print(p-value:, result[1]) print(Critical Values:, result[4]) adf_test(df[sales]) # 假设输出p值0.8 0.05不平稳进行一阶差分并重新检验df[diff_1] df[sales].diff(1).dropna() adf_test(df[diff_1]) # p值0.02 0.05平稳此时d1。接下来通过ACF/PACF图确定p和qfig, (ax1, ax2) plt.subplots(2,1, figsize(12,8)) plot_acf(df[diff_1], lags20, axax1) plot_pacf(df[diff_1], lags20, axax2) plt.show()根据图形特征PACF在lag2后截尾 → p2ACF在lag1后截尾 → q1也可以使用网格搜索确定最优参数best_aic np.inf best_order None for p in range(0, 3): for d in range(0, 2): for q in range(0, 3): try: model ARIMA(df[sales], order(p,d,q)) results model.fit() if results.aic best_aic: best_aic results.aic best_order (p,d,q) except: continue print(fBest ARIMA{best_order} with AIC{best_aic:.2f})3. 模型训练与验证拆分训练集和测试集保留最后12个月验证train df[:-12] test df[-12:] model ARIMA(train[sales], order(2,1,1)) model_fit model.fit() print(model_fit.summary())关键输出解读coef列各参数权重及显著性P|z|应0.05Ljung-Box残差自相关检验p值应0.05Jarque-Bera残差正态性检验进行滚动预测验证history train[sales].tolist() predictions [] for t in range(len(test)): model ARIMA(history, order(2,1,1)) model_fit model.fit() yhat model_fit.forecast()[0] predictions.append(yhat) history.append(test[sales][t]) rmse np.sqrt(mean_squared_error(test[sales], predictions)) print(fTest RMSE: {rmse:.2f})4. 预测优化与业务应用通过以下技巧可进一步提升效果技巧1Box-Cox变换处理异方差from scipy.stats import boxcox train[trans], lam boxcox(train[sales]) # 预测后需用inv_boxcox还原技巧2引入外部变量# 添加促销活动指标 model ARIMA(train[sales], exogtrain[promo], order(2,1,1))技巧3残差诊断可视化residuals pd.DataFrame(model_fit.resid) residuals.plot(kindkde) # 应接近正态分布最终预测未来12个月销售final_model ARIMA(df[sales], order(2,1,1)) final_fit final_model.fit() forecast final_fit.get_forecast(steps12) # 获取置信区间 conf_int forecast.conf_int() forecast_index pd.date_range(df.index[-1], periods13, freqM)[1:] # 可视化 plt.figure(figsize(12,6)) plt.plot(df.index, df[sales], labelHistorical) plt.plot(forecast_index, forecast.predicted_mean, colorr, labelForecast) plt.fill_between(forecast_index, conf_int.iloc[:,0], conf_int.iloc[:,1], colorpink, alpha0.3) plt.title(12-Month Sales Forecast with 95% CI) plt.legend()将预测结果转化为业务建议库存准备根据预测下限确保基础库存营销预算参考预测中值分配资源风险预案对置信区间上界做产能准备