ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

销量预测实战:指数平滑+灰色预测+IOWA组合模型解析

销量预测实战:指数平滑+灰色预测+IOWA组合模型解析 简介《新能源电动车销量预测模型的应用》是一份面向新能源行业研究者、政策制定者及车企市场分析人员的学术文献聚焦电动车销量预测方法。研究以2012—2015年16个季度全国乘用车销量数据为基础选用二次指数平滑法刻画线性趋势将季节变动指数融入灰色预测以处理季度波动并引入IOWA算子按预测精度动态赋权构建组合预测模型最终通过2016年四个季度销量预测验证了可行性与有效性。资源包为单个PDF文档大小约1.07MB内容包含完整建模步骤、公式推导与实例仿真结果适合需要系统了解销量预测流程或参考学术论文写作方法的读者。目前已有148人学习可作为新能源市场研究、灰色系统与组合预测方向的专业参考文献。1. 新能源电动车销量预测三个模型叠起来比单个模型稳得多销量预测这件事单独看好像很简单拿到一列历史数据就往外推。但新能源电动车乘用车的销量数据有它自己的脾气整体向上增长同时一季度和四季度有明显的季节起伏中间还夹着政策补贴切换带来的突变。用单一模型去拟合这种序列结果往往很飘今天讲线性、明天讲趋势后天直接失灵。这篇论文给了一个非常务实的做法先用二次指数平滑做趋势拟合再用季节变动指数改进灰色预测 GM(1,1)最后用 IOWA 算子把两个模型按预测精度动态加权组合。结果是平均相对误差从 74.72% 和 44.26% 压到了 20.46%预测 2016 年全年销量约 57.19 万辆。对做销售预测、做市场策略、订生产计划的从业者来说这套组合思路可以直接迁移到自己的数据上不一定照抄公式关键是理解它怎么处理「趋势 季节 突变」三类问题。下面拆开讲。2. 二次指数平滑先抓住趋势再谈预测精度2.1 为什么是二次不是一次也不是三次指数平滑是时间序列预测最朴素的工具之一。一次指数平滑适合没有明显趋势的稳定序列它本质上是对历史数据做加权平均越近的数据权重越大。但当序列存在线性上升趋势时一次平滑的值总是滞后于实际值因为平滑值本质上是历史水平的加权汇总追不上趋势。二次指数平滑解决的就是这个问题在一次平滑的基础上再做一次平滑然后通过两个平滑值构造出截距项和斜率项从而拟合线性趋势。论文在三种平滑方法中选了二次依据很简单——新能源电动车销量的变化趋势总体是线性增长的没有出现明显的曲率。如果你打开数据看到的是一个近似直线的上升形态二次指数平滑是对路的如果序列有明显的加速或减速才需要上三次平滑。import numpy as np def double_exp_smoothing(series, alpha): # 一次平滑 s1 np.zeros(len(series)) # 二次平滑 s2 np.zeros(len(series)) s1[0] series[0] s2[0] series[0] for t in range(1, len(series)): s1[t] alpha * series[t] (1 - alpha) * s1[t - 1] s2[t] alpha * s1[t] (1 - alpha) * s2[t - 1] # 模型参数截距 at 和斜率 bt at 2 * s1[-1] - s2[-1] bt (alpha / (1 - alpha)) * (s1[-1] - s2[-1]) return at, bt, s1, s2公式对应论文中的式1到式5。s1是一次平滑值序列s2是二次平滑值序列at是当前水平的估计bt是每个周期的增量估计。alpha是平滑系数取值范围 0 到 1它决定了历史数据的衰减速度。alpha的选取是这一步唯一的超参数论文用试算的方式结论是 0.6 时精度最高这符合销量数据的特性——近期信息权重应当偏大。实际使用中可以用网格搜索遍历 0.05 到 0.95对每个alpha做回测计算拟合误差的均值选误差最小的。注意不要光看训练集误差要留最后两期做验证防止过拟合到历史噪声上。2.2 预测公式怎么用拿到了at和bt第tT期的预测值就是at bt * T。这就像从当前水平拉一条直线往外延伸。短期预测没有问题但拉长到三四个季度之后趋势假设是否还成立就要打个问号。论文的原始数据只有 16 个季度用前 14 期拟合、后 2 期验证这种数据量下二次指数平滑的误差被放大得很快这就是为什么单独用它不够必须要引入别的模型来兜底。2.3 单独跑二次指数平滑的短板我给这段加一句提醒二次指数平滑能抓住线性趋势但它对季节性是「看不见」的。新能源电动车一季度销量偏低、四季度冲量这种周期波动在指数平滑里会被当作随机噪声吃掉。如果直接用第 16 期的水平加斜率去推第 17 期得到的预测值大概率落在真实值上方或下方一大截。所以论文用了一次指数平滑做初筛真正落到预测的是后面的组合模型。3. 改进的灰色预测给 GM(1,1) 加上季节矫正3.1 灰色预测的底层逻辑灰色预测 GM(1,1) 的核心思想是把原始序列做一次累加生成1-AGO把一段波动明显的数据变成近似指数增长的单调序列然后对这个累加序列拟合一个一阶线性微分方程最后累减还原回原始尺度。对新能源电动车销量这种既有增长趋势又有波动的数据灰色预测能抓住总量增长的那条主线但对季节波动天然不敏感。论文的改进点很直接灰色预测算出的拟合值在还原之后再乘上一个季节变动指数。这个指数的计算方式是把每个季度的历史平均值除以全部季度的总平均值。比如四年里第一季度平均销量是全部季度平均销量的 0.7 倍那第一季度的指数就是 0.7预测值整体往低调 30%。3.2 季节变动指数的计算import numpy as np def seasonal_index(data, n_quarters4): # data: 按季度排列的销量数组长度必须能被4整除 data np.array(data).reshape(-1, n_quarters) # 每个季度的多年平均值 quarter_avg data.mean(axis0) # 所有季度的总平均值 overall_avg data.mean() # 季节变动指数 ci quarter_avg / overall_avg return ci sales_2012_2015 np.array([ 1614, 1468, 1337, 5485, 2518, 2291, 2104, 8093, 12254, 9150, 8192, 28952, 26300, 25104, 45177, 80046 ]) ci seasonal_index(sales_2012_2015) print(季节变动指数:, ci)算出来的四个指数季节分布会很明显一季度和三季度偏低四季度畸高这正是电动车市场年末冲量的典型特征。reshape(-1, 4)这一步把一维序列拆成「年份 × 季度」的矩阵每行是一整年每列是同一季度。mean(axis0)得到的是每个季度的跨年平均。这个指数一旦算出来就作为固定系数乘到灰色预测的还原值上。3.3 灰色预测的建模流程灰色建模有几个固定步骤先对原始序列做累加生成构建紧邻均值序列然后用最小二乘法估计发展系数a和灰作用量p最后写出时间响应式。论文里给出了一组真实参数值a -0.3217p -1279.1对应的离散响应式是x(k1) 2036.03 * exp(0.3217 * t) 4836.16。import numpy as np def gm11(series, forecast_len4): series np.array(series, dtypefloat) n len(series) # 1-AGO 累加生成 x1 np.cumsum(series) # 构造紧邻均值序列 z1 (x1[:-1] x1[1:]) / 2.0 # 构造 B 矩阵和 Y 向量 B np.column_stack([-z1, np.ones(n - 1)]) Y series[1:].reshape(-1, 1) # 最小二乘估计参数向量 [a, p] params np.linalg.inv(B.T.dot(B)).dot(B.T).dot(Y) a, p params[0][0], params[1][0] # 时间响应式 x1_hat (series[0] - p / a) * np.exp(-a * np.arange(1, n forecast_len)) p / a # 累减还原 x0_hat np.zeros(n forecast_len) x0_hat[0] x1_hat[0] for i in range(1, n forecast_len): x0_hat[i] x1_hat[i] - x1_hat[i - 1] return x0_hat, a, pB矩阵的第一列是-z1这是灰色模型的紧邻均值第二列全 1。Y是原始序列去掉第一个值后的向量。最小二乘求解(B^T B)^(-1) B^T Y对应论文的式9。还原后的x0_hat要再乘上季节变动指数才是最终预测值也就是论文的式14y x̂ * Ci。3.4 这个模型的边界灰色预测的假设是序列背后有一个指数增长规律。当数据本身增长放缓、出现政策天花板的时候a的绝对值会变小模型拟合出来的增长率会失真。论文数据是 2012 到 2015 年刚好是新能源车补贴政策力度最大的阶段指数增长假设是成立的。放到今天看市场规模大了增速下来了直接用 GM(1,1) 会出现系统性高估。这时候改进的方向不是堆更多修正系数而是考虑上 Logistic 增长曲线或引入外部变量。4. 基于 IOWA 算子的组合预测按预测精度动态分配权重4.1 组合预测的痛点组合预测不是新鲜概念通常做法是给几个模型固定权重加权平均。但问题在于指数平滑和灰色预测在不同时点表现各不相同——有的季度指数平滑更准有的季度灰色预测更稳。固定权重相当于用一个平均表现去替代每个时点的局部最优浪费了信息。IOWA 算子解决的正是这个问题每个时点上把各模型的预测精度作为诱导值精度高的模型在当前时点拿走更大的权重。诱导值就是预测精度a_it计算方式是1 - |(x_t - x_it) / x_t|如果相对误差超过 100% 就记 0。这个值的含义很直白谁这个季度预测得准谁下个季度说话更算数。4.2 权重求解的核心步骤import numpy as np from scipy.optimize import minimize def iowa_weight_error(w, errors_ranked): # errors_ranked: 按精度降序排列的误差序列每行是一个时点 n len(errors_ranked) total 0.0 for t in range(n): for i in range(len(w)): for j in range(len(w)): total w[i] * w[j] * errors_ranked[t][i] * errors_ranked[t][j] return total # 以论文两种单项模型为例改进灰色预测时点误差和高精度时点的对应关系 # 这里按论文整理后的误差平方和矩阵代入 E np.array([ [792944854.0, -815129028.0], [-815129028.0, 7156651702.0] ]) def objective(w): return E[0][0] * w[0]**2 2 * E[0][1] * w[0] * w[1] E[1][1] * w[1]**2 cons ({type: eq, fun: lambda w: w[0] w[1] - 1}, {type: ineq, fun: lambda w: w}) res minimize(objective, [0.5, 0.5], bounds[(0, 1), (0, 1)], constraintscons) print(res.x) # 得到约 [0.83, 0.17]这段代码对应论文式18的二次规划问题。目标函数是组合预测误差平方和约束条件是权重和为 1、每个权重非负。论文用 MATLAB 最优化工具箱求解我这里用scipy.optimize.minimize是等价的。注意E矩阵是对称的交叉项在展开时要乘 2。论文给的最优权重是 ω₁ 0.83、ω₂ 0.17说明在这个样本区间内改进灰色预测的贡献远大于指数平滑。4.3 外推预测时精度序列怎么更新对未来做预测时没有真实值可以算精度。论文的处理方式是用最近 K 期的平均精度作为下一期预测精度的替代预测 2016 年四个季度时就用样本区间最后四期的平均精度来排序。这是「历史精度代表近期表现」的假设在数据没有结构性突变时成立。如果出现补贴政策调整、新车型投放这类事件这个假设会被打破你需要在代码里加入人工修正权重的入口不能只依赖自动计算。4.4 三种模型对比看效果论文表 2 给出了三组平均相对误差二次指数平滑 74.72%改进灰色预测 44.26%IOWA 组合预测 20.46%。数量级差别很明显。需要注意的是二次指数平滑的误差高不是因为公式错了而是数据本身季节性太强线性模型天然吃亏。组合预测把灰色预测的季节矫正能力保留下来又用精度诱导机制把局部最优的预测值挑出来加权才把误差压到 20% 左右。5. 复现避坑与常见问题五个踩出来的教训5.1 平滑系数 α 不能凭感觉定现象给定 α0.2 和 α0.8二次指数平滑的拟合结果差距非常大用 α0.2 时预测值严重滞后于实际走势。原因α 控制历史数据衰减速度新能源车销量增长快历史远期的信息价值有限平滑系数太小会让模型过度依赖早期数据。解决用网格搜索从 0.05 到 0.95 步长 0.05 遍历对每个候选值做留一法或滚动验证取验证集平均绝对误差最小的 α。论文采用 0.6我复现时在自己数据上得到的是 0.55差异不大。5.2 季节变动指数不能拿全部历史数据平均现象季节变动指数算出四季度系数高达 1.8 以上一季度只有 0.4 左右直接用这个系数矫正灰色预测导致部分季度预测值被压得过低。原因2012 到 2015 年新能源车销量基数低季度间绝对差异小但指数计算的是相对比例小基数年份的波动会放大指数。解决如果数据只有四五年建议逐年计算指数后检查稳定性剔除明显异常的年份再求平均。或者用最近三年的数据计算指数不要贪多。5.3 IOWA 权重求解出现负权重现象直接套用二次规划求解 ω 时某些权重解出来是负数不符合组合预测的常识误差平方和反而很小。原因目标函数是纯数学的最优化没有约束权重非负的时候负权重可以通过模型间的误差对冲把整体误差降下来但这是数学技巧不是预测逻辑。解决在优化模型里强制约束ω_i 0并加权重和为 1 的等式约束。用scipy.optimize.minimize时设置bounds[(0, 1), ...]就能避免这个问题。5.4 灰色预测累减还原后出现负值现象原始数据本身全是正数但从累加序列还原时个别时点还原值变成负数。原因累减时x1_hat[i] - x1_hat[i-1]相邻两个累加值过于接近如果拟合的指数函数在某个区间的斜率趋近 0差值就会小于 0。解决检查拟合参数a的绝对值如果|a|小于 0.01说明序列接近水平灰色模型不适用换差分或直接线性外推。也可以用滑动窗口把预测值限幅到下界 0。5.5 组合预测精度反而不如单项模型现象把两个表现都一般的模型组合起来组合预测误差比其中较好的一个还大那 IOWA 算子就失去了意义。原因IOWA 组合的前提是两个模型的误差模式具有互补性——各有时段占优而不是一个模型在所有时点都碾压另一个。如果其中一方的精度始终高权重会集中给它组合几乎没有增益。解决在拟合区间上分别画出两种单项模型的误差曲线肉眼确认它们存在交替领先。如果误差曲线同步起伏组合大概率没有增益。这个检查属于常见的操作习惯动手前先花两分钟看一眼能省很多后面调试的时间。6. 验证模型是否真的可信从误差到业务的完整闭环模型建完不等于能用尤其是做销量预测这种直接牵动采购和排产决策的任务。我自己的习惯是用一套固定的验证流程把关每过一个关卡才敢把预测结果交给业务方。第一步是看拟合误差的分布。单看平均相对误差 20.46% 还不够得把 16 个季度的相对误差摊开看确认没有某个季度误差奇高。论文的误差图里有几个点超过了 50%这些通常是政策变动带来的异常点。对于异常点我一般会单独标注不让它们进入下一个预测周期的精度序列否则会污染 IOWA 算子的权重分配。这里可以用一个简单的判断函数相对误差超过三倍中位数标准差就视为异常。第二步是验证加权权重是否稳定。权重是 IOWA 组合模型的核心参数如果样本区间只改一个季度ω₁ 就从 0.8 跳到 0.4说明模型对训练数据过于敏感外推预测会很不稳定。做法是把 16 个季度切成两个 8 季度的窗口分别求解权重对比两组权重差异差异超过 0.3 就需要找原因。第三步是回测 2016 年预测值。论文预测 2016 年四个季度合计 57.19 万辆实际值出来后可以反查。如果预测值明显偏离优先怀疑季节变动指数是否发生变化——比如补贴退坡导致四季度冲刺效应减弱。这里给一张验证检查表方便直接对照排查检查项通过标准失败时的处理季节变动指数4 个季度指数跨度在 0.51.9 之间跨度异常说明有政策或事件影响换最近三年数据重算权重稳定性两个时间窗口的权重差不超过 0.3不稳定则检查两个单项模型的误差曲线是否互补外推一致性预测序列与最近两个季度的增长斜率方向一致斜率相反时检查灰色模型的发展系数考虑替换模型基本面交叉验证预测增速不超过行业政策目标增速的两倍超过时引入就业率、补贴退坡等外部变量做定性判断做完这四步模型给出的数字才值得往报告里放。从那以后我每次做类似的时间序列预测项目都会强制走一遍上面的流程先画误差曲线判断模型互补性再调 α、算季节指数、解 IOWA 权重最后做稳定性回测。预测这件事真正翻车的通常不是某一个公式写错而是在模型环节跳过了交叉验证。多花半小时做验证比事后跟业务方解释误差原因要省心得多。希望这些经验能帮你在自己的数据上少踩几个坑。本文还有配套的精品资源点击获取
返回列表