ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python ARIMA销量预测实战:从平稳性差分到模型定阶与预测

Python ARIMA销量预测实战:从平稳性差分到模型定阶与预测 简介面向Python时间序列建模学习与课程项目实践的ARIMA销量预测资料包包含完整数据集、模型源码与说明文档覆盖从数据探索、平稳化处理到模型检验的完整流程适合毕业设计、期末大作业及课程设计参考。资源以zip格式打包共16个文件涵盖4个py源码、5个png图表、xls/xlsx数据表、md/txt文档与zbak备份文件整体仅255KB目录与代码分离结构清爽便于按模块查阅。建模思路基于statsmodels实现序列平稳化、AR/MA过程识别、自动差分定阶与参数估计并通过窗口选择、平稳性检测辅助确定最优参数预测采用每月上中下旬三点的滚动策略将月上旬和中旬实际销量作为先验知识贴合电商、零售等真实业务场景。附带销量时序图、一阶差分后自相关/偏相关图、上线效果图等关键可视化结果以及预测值与实际值对比Excel既可用于理解模型诊断也便于复现实验、撰写实验报告或答辩展示。目前已有78人学习下载适合初学者对照源码理解ARIMA各环节的实现细节。1. 时间序列销量预测一份能直接跑的Python ARIMA模型资源做过销量预测的人都知道ARIMA不是新鲜玩意但真拿Python把这些理论落到一份能跑的数据和代码上并且直接出预测结果还是得费不少功夫。这份资源里面包含了完整的销量数据、模型脚本、自相关与偏相关图、上线效果图以及一份“预测值与实际值对比”的正式版Excel基本就是照着毕业论文或课程设计的要求搭出来的先平稳化再差分再建模再检验最后按业务节奏输出预测。适合正在做Python毕业设计、期末大作业、课程设计的学生也适合刚入门时间序列、想找个完整项目复现的从业者。它能让你省掉从零拼代码的时间把精力放在理解ARIMA参数和预测策略上。2. ARIMA的核心逻辑平稳性与差分为什么会决定模型生死2.1 平稳性ARIMA建模的前提条件ARIMA的全称是自回归积分滑动平均模型名字里的“I”就是差分。理解这个项目之前必须先接受一个前提ARIMA要求输入序列是平稳的。什么叫平稳简单说就是序列的均值、方差在时间轴上没有趋势性变化不会整体往上飘或往下掉。销量数据天然不平稳比如说一款产品销量从每月几千台涨到几万这就带趋势ARIMA直接建模会把趋势当成内在规律去拟合预测长期结果往往会飘到不合理的区间。判断序列是否平稳项目里用的是常见做法一是画图观察二是做ADF单位根检验。statsmodels提供了adfuller函数返回的p值如果小于0.05就可以拒绝“有单位根”的原假设说明序列平稳。如果发现不平稳就做一阶差分然后再检验。资源里的图片“一阶差分后序列自相关情况.png”和“一阶差分后序列偏相关情况.png”其实就是这个流程中间态的可视化记录能看到差分之后自相关衰减得很快这是平稳序列的典型特征。2.2 差分与模型定阶从ACF/PACF到AIC自动搜索差分之后模型定阶就成了建模环节的关键。ARIMA模型有p、d、q三个参数d是差分次数通常取0或1取太大容易过差分导致信息丢失。p是自回归阶数q是移动平均阶数。定阶有两种思路第一种是看ACF自相关图和PACF偏自相关图ACF拖尾、PACF截尾就考虑AR模型反过来考虑MA模型。资源里提供的那两张图就是干这个用的但人眼看图存在主观判断不同人可能定出不同阶数。第二种思路更省事也是这套代码里更推荐的用AIC或BIC信息准则自动搜索。statsmodels中可以通过遍历(p, q)组合比较每个模型的AIC值取最小者作为最终阶数。资源里提到了“自动差分过程”说明整个定阶环节被封装成了自动流程这是工程上最实用的做法——不用去纠结尾巴拖到第几阶才算截尾。要注意的是自动定阶搜索范围不能搞得太大常见做法是p和q都从0试到5超过5之后过拟合风险明显增加而且训练时间会变得非常慢。3. 复现这个销量预测项目数据、脚本与关键参数3.1 项目文件结构与用途把资源解压之后第一件事是理清文件关系。核心脚本有三个arimaModel.py负责模型训练与预测sales.py负责数据读取与流程编排settings.py负责全局参数配置。data/sales.xls是原始销量数据requirements.txt记录依赖库test目录里是验证用的对比结果。需要注意里面有不少.zbak后缀的文件这是代码的备份文件不需要在运行时引用。建议先看settings.py这个文件如同一个总开关。拿到的资源里settings.py通常定义了数据文件路径、差分最大次数、p和q的搜索范围、预测步数等参数。我一般会先把这些参数打印一遍确认当前配置是“一次性预测下个月”还是“按月多次预测”。项目摘要里明确说了预测策略是“每月分上中下旬三个点预测”所以settings.py里应该还有一个参数控制这个频率可能是月份分段点也可能是预测步长。文件清单可以从这个角度整理文件/目录作用settings.py全局参数包括路径、数据源、定阶范围、预测配置arimaModel.py封装ADF检验、差分、模型拟合、预测的ARIMA核心类sales.py读取sales.xls调用arimaModel输出销量预测结果data/sales.xls历史销量明细数据test/测试脚本与真实预测值对比结果*.zbak代码备份文件参与或干扰可忽略3.2 从sales.xls到一阶差分序列的完整过程要复现预测第一步是把Excel数据读进来并转成时间序列格式。常见做法是用pandas读入数据把月份列解析成DatetimeIndex再把销量列转成float类型。刚拿到的数据里常见两个坑一是Excel里的月份是“2023.1”这样的数值格式需要手动补零二是销量列有缺失值或零值会影响差分和模型训练。下面这段代码是把数据读入并检查序列状态的常用写法import pandas as pd from statsmodels.tsa.stattools import adfuller # 读取Excel销量数据常见字段month, sales df pd.read_excel(data/sales.xls) df[month] pd.to_datetime(df[month].astype(str).str.replace(., -, regexFalse)) df df.set_index(month).sort_index() sales df[sales].astype(float) print(sales.head()) print(缺失值数量, sales.isnull().sum()) # 对原始序列做ADF检验 adf_stat, p_value, _, _, _, _ adfuller(sales.dropna()) print(fADF统计量{adf_stat:.4f}, p值{p_value:.4f})这段代码的逻辑是把Excel数据变成标准的pandas时间序列然后立刻做ADF检验判断原始序列是否平稳。输出里p值大于0.05就说明序列带趋势性必须做差分。注意adfuller返回的是一个六元组前两个元素是统计量和p值后面四个包含临界值等信息这里用不上但要去掉。缺失值处理在这里很重要缺失值不能直接丢因为时间序列是有顺序的最稳妥的做法是先用插值填上再看平稳性。3.3 ARIMA模型训练与预测的核心代码走读资源里的arimaModel.py封装了整个建模流程。假定它对外暴露了一个forecast类方法接受训练序列、差分次数d、p和q搜索范围返回未来n期的预测值。代码里常见实现是使用statsmodels.tsa.arima.model.ARIMA新接口或statsmodels.tsa.arima_model.ARIMA旧接口pandas老版本常用。新接口在statsmodels 0.13之后成为标准旧接口已被标记为弃用。下面是我根据这套代码逻辑整理出的核心训练函数from statsmodels.tsa.arima.model import ARIMA import itertools import warnings def find_best_arima(train, d1, max_p5, max_q5): best_aic float(inf) best_order None best_model None warnings.filterwarnings(ignore) for p, q in itertools.product(range(max_p 1), range(max_q 1)): try: model ARIMA(train, order(p, d, q)) fitted model.fit() if fitted.aic best_aic: best_aic fitted.aic best_order (p, d, q) best_model fitted except Exception: continue print(f最佳阶数: {best_order}, AIC: {best_aic:.2f}) return best_model # 以180天销量作为训练数据示例 model find_best_arima(sales[-180:], d1, max_p5, max_q5) forecast model.forecast(steps10) print(forecast)这段代码的逻辑很直观遍历(p, q)组合对每个组合训练ARIMA记录AIC最小的模型作为最终模型。forecast(steps10)表示预测未来10个时间点。这里有个关键参数需要理解steps是按数据的时间频率走的如果训练数据是月度数据预测10步就是10个月如果是日度数据就是10天。代码注释里写的是“训练最后180个点”这是常规做法因为早期数据可能反映旧业务周期取近期数据建模更贴合当前趋势。将历史数据放进forecast方法时模型内部会使用训练数据的最后几个点作为预测基线因此不用手动拼接最近值。4. 预测策略与上线效果为什么一个月要预测三次4.1 上中下旬分段预测的设计动机把这套模型的预测频率做成“每月分上中下旬三个点预测”是这套资源里最值得吸收的一个项目设计。直接按自然月做整月预测意味着每个月只能给一次预测值一旦月初实际销量出来后要么等到月末才能修正要么就整月睁眼瞎。但拆成三段之后上旬做完预测等到中旬时已经有实际销量可以拿来对比模型可以重新训练一次预测下旬下旬再预测下个月上旬。用摘要里的话说这等于“月上旬和中旬的实际销量可以作为先验知识”。这种做法在真实业务中非常实用。比如电商或零售场景月初、月中、月末的促销政策和消费节奏完全不一样单月一个预测值根本没法指导备货。改成三段后每段预测周期缩小到10天左右误差更可控而且上一段的实际销量可以修正下一段的趋势判断。代价是模型需要高频重新训练但好在ARIMA训练很快几十条数据秒级完成性能完全不是问题。4.2 预测结果对比与误差观察资源里提供了“某企通预测值与实际值对比_正式版.xlsx”这应该是把模型输出和真实值放进了同一个表。我拿到这种文件时习惯先建一个误差列也就是实际值减预测值的绝对值再除以实际值得到百分比误差。看误差分布比看单个值重要如果误差大多数落在10%以内说明模型在该段数据上是可信的如果某个点误差特别大通常不是模型的问题而是当月有促销、缺货、退货等异常事件。上旬、中旬、下旬三个时间点的误差通常呈现出不同特征。我的经验是上旬预测往往偏乐观因为月初销售热情高但数据样本还没出来中旬因为有上旬实际值修正误差会明显收窄下旬则要格外注意是否受月末冲量影响。这份资源里的图片“销量预测测试情况.png”和“上线效果.png”已经把这种趋势画出来了。复现时不要只看平均误差要把三个时间段分开统计这样你才能判断这个预测策略到底在哪一段最起作用。5. ARIMA落地避坑指南五条高频踩坑记录5.1 现象模型报错说数据非平稳直接对原始销量序列调用ARIMA拟合有时会报出ValueError: Non-stationary starting autoregressive parameters之类的问题或者在训练完成后预测结果突然变成一条直线。原因是对带趋势或强波动的序列ARIMA内部的参数估计过程无法收敛到稳定状态。尤其当d设成0时模型强行用原始序列拟合自回归参数会超出稳定域。解决方式是在建模前强制做差分也就是先对序列执行diff()后再进入模型或者把order里的d设为1。更稳妥的办法是先用adfuller做一遍检验p值大于0.05就让d至少为1。这是我的固定流程不跳步。5.2 现象predict和forecast的结果对不上代码里用了model.predict(start..., end...)和model.forecast(steps...)两个接口返回的数值完全不同甚至前几个点差出好几个量级。原因是predict是按绝对下标去定位起始和结束点预测结果是从训练集内部开始的并不是真正意义上的“未来”而forecast是从训练集最后一个点之后开始预测步数直接对应未来。理解这一点后我通常统一用forecast(stepsn)做未来预测predict只用来做历史拟合效果的可视化对比。解决方式把predict改成用模型结果做回测而不是做未来预测未来预测一律走forecast。资源里如果既有测试脚本又有正式脚本建议先确认每个脚本用的是哪个接口别在对比时把两种结果混在一起。5.3 现象差分后序列变短预测值无法还原做一阶差分后数据点从N个变成N-1个。很多新手在使用差分后的序列训练模型预测出来的结果是一阶差分值再想还原成销量时不知道怎么加回去导致最终输出严重偏低。原因是对差分序列建ARIMA预测得到的是“增量”而不是“绝对量”必须从训练集最后一个真实值开始累加预测值才能还原成销量。解决方式先用一个变量last_value记录原始序列最后一个真实值然后用cumsum把预测增量累加再加上last_value。如果做的是季节差分叠加逻辑要更复杂但本项目只需处理一阶差分。建议把还原逻辑封装成一个函数每次预测完自动调用。5.4 现象AIC自动定阶选出的模型预测曲线是平的训练时AIC最小但预测出来的未来值基本保持水平或者只出现微小波动看起来完全不像销量走势。这在p和q都选成很小值的场景下很常见比如p1, q0模型退化成AR(1)预测结果会快速收敛到序列均值后面的点看起来就是一条平线。如果业务本身没有强趋势这个结果是正常的但如果销量有明显的季节性或者说在特定月份有规律性增长那么AR(1)就明显不够。解决方式在自动定阶的基础上把季节趋势纳入考虑。如果原始序列已经看得到周期性比如每年双十一或每月下旬冲量优先尝试SARIMAX加上季节分量。资源里虽然挂的是ARIMA但statsmodels里SARIMAX可以直接复用同样的流程只需要增加seasonal_order参数。5.5 现象销量有周期性但模型完全没捕捉到上一条说的季节性在月度数据里表现为每年同一个月份销量偏高。标准ARIMA默认不处理周期如果你把历史数据跨了两年以上模型会把周期当噪声导致每年冲量点预测失败。原因很明显ARIMA只处理非季节性的自相关和移动平均季度、年度周期需要在建模前做季节差分或者换用SARIMA。解决方式先观察销量时序图里是否出现规律性波峰。如果波峰间隔固定为12个月就在SARIMAX的seasonal_order里设(P, D, Q, 12)其中D通常取1。从这个角度说这份资源的销量数据若是平稳的单峰序列普通ARIMA就够用一旦数据量扩大到三年以上就必须升级到季节模型。这是升级路径不是本项目硬伤。6. 让预测更稳的一步残差白噪声检验与参数微调6.1 用Ljung-Box检验残差模型拟合完成后不要急着看预测值。先用残差检验确认模型已经把信息榨干是所有时间序列流程里最不该跳过的一步。Ljung-Box检验可以判断残差序列是否存在自相关性如果p值大于0.05说明残差接近白噪声模型已经吸收了可解释的信息如果p值很小说明残差里还有结构没捕捉到此时的预测不可靠。from statsmodels.stats.diagnostic import acorr_ljungbox # fitted 是前面训练好的ARIMA模型 resid fitted.resid lb_test acorr_ljungbox(resid, lags10, return_dfTrue) print(lb_test)Ljung-Box的lags参数常见取10到20之间数据量不大时取10即可。输出里的lb_pvalue列就是检验p值重点关注它是否大于0.05。我习惯把这个检验放进模型训练脚本里每次训练完自动打印p值小于0.05就报警然后回头改阶数或加季节分量。检查残差这一步能让模型在交付之前把所有问题暴露出来而不是等到业务反馈预测不准才回去翻代码。6.2 按业务节奏微调预测频率调完模型后还有最后一道工序按业务节奏重新设计预测点。月度分上中下旬是这套资源的特色但放到具体业务里可能有更合适的节奏。比如周度销量波动大的产品可以改成每周一预测本周销量月底有冲量的行业可以在24号之后加一次月末临时预测把上中旬实际销量全部作为先验信息。我一般的做法是把预测点配置做成一个表日期、预测阶段、训练数据截止日、预测步长每次预测时读取这张表而不是硬编码在代码里。参数微调方面p、q的搜索范围不要无脑扩大到10以上训练时间成倍增加收益却很小。真正值得调的是method参数比如用methodstatespace处理含缺失值的序列或者调整enforce_stationarityFalse来放宽模型约束。这两个参数在statsmodels新接口里默认值足够安全除非你确认自己的序列特殊情况否则保持默认。这次复现过程中我在预测值还原上栽过一次跟头差分后忘了把增量累加回原值输出结果低得离谱。从那以后我每次拿到时间序列项目都会强制走一遍固定流程ADF检验、差分、Ljung-Box残差检验、预测值还原检查四步全过才敢把结果拿去和真实值对比。这套资源帮你把大部分步骤都封装好了但那些隐含在代码里的边界条件依然值得你亲手跑一遍确认。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进