拓冰建站拓冰建站
首页 / 资讯中心 / 正文

分数阶累加DGM(1,1)模型:原理、Python实现与调参实战

简介面向数据挖掘与预测建模开发者的DGM灰色模型资源包重点解决小样本、非线性、非平稳时间序列的预测问题涵盖分数阶累加技术及其在动态灰色模型中的具体实现。DGM模型以微分方程刻画数据变化规律结构简洁且适应性强分数阶累加则通过调节阶数改善平滑程度从而提升预测精度。资源共4个文件包含3个Matlab源码脚本与1张桌面示意图包体仅62KB脚本分别对应累加、累减与DGM模型解算等核心环节jpg图片可辅助梳理建模流程。压缩包内文件组织清晰脚本调用关系直接明了便于对照灰色系统理论中的公式逐步验证示意图则能直观展示分数阶累加前后的序列变化。该资源已有255人学习使用适合想深入理解分数阶灰色模型原理的研究者或需要快速搭建预测原型的工程师可结合描述中的数学推导理解各函数作用并根据自身数据灵活调整阶数参数获得更准确的预测结果。1. 为什么 DGM 模型仍值得用分数阶累加重做一遍如果你从网上拿到一个 DGM.rar 压缩包很常见的结果是代码里写死了一次累加跑训练集时 MAPE 很小换一组数据就明显偏差。问题通常不是出在 DGM 本身而是“一次累加”这个默认操作把数据的变化结构定死了。DGM(1,1) 是离散灰色模型相比传统 GM(1,1) 少了一层“微分转差分”的误差但它的累加阶数默认是 1等于只能表达一种记忆衰减速度。分数阶累加把累加次数从整数放宽到实数 r相当于给模型加了一个可调旋钮r 越小越看重近期数据r 越大历史平滑越强。于是原本不拟合的趋势可以通过搜索 r 找到合适的变换。下面从数学原理、可运行的 Python 实现到调参步骤依次说明适合需要用短序列出预测结果、又想真正理解灰色预测边界的工程师。2. 分数阶累加与 DGM(1,1) 的数学基础从灰导数和离散差分说起2.1 传统 GM(1,1) 的漂移问题与 DGM 的离散化修正传统灰色模型先对原始序列 x^(0) 做一次累加得到 x^(1)再建立一阶灰色微分方程x^(0)(k) a z^(1)(k) b其中 z^(1)(k) 是 x^(1) 的背景值通常取相邻两项的平均。估计出 a、b 之后模型套用连续微分方程的解来做预测。这中间藏着一个结构性问题参数是在差分方程里估计的预测时却使用连续指数解估计域和预测域不一致。当样本量很短、数据波动较大时这个错位会被放大造成预测值整体漂移。DGM(1,1) 的思路是去掉微分方程直接对离散累加序列 x^(1) 建立递推式x^(1)(k1) β1 * x^(1)(k) β2β1、β2 用最小二乘从离散数据中直接估计。预测时也按这个差分方程外推不再套用连续解析式。这样灰色模型被简化成一个带线性强迫项的一阶自回归模型参数估计和预测使用同一个离散框架稳定性明显提高。对大多数工程数据来说DGM 的滚动预测优于 GM(1,1)这也是后续许多改进模型选择 DGM 作为骨架的原因。但要注意DGM 的本质是线性递推。它适合强指数趋势遇到局部拐点或者趋势突变时依然会失准。想要在不改变递推结构的情况下提升适应力就得修改累加算子也就是引入分数阶累加。2.2 分数阶累加生成算子与阶次 r 的含义分数阶累加不改变 DGM 的递推形式只改变所有样本进入模型时的权重分配。定义 r 阶累加序列x^(r)(k) Σ_{i1}^k C(k - i r - 1, k - i) * x^(0)(i)这里的 C(n, m) 是实数域推广的组合数C(n, m) n(n - 1)...(n - m 1) / m!m 0 时值为 1当 r 1 时组合数恒为 1退化成普通一次累加当 r 0 时序列不变。r 在 0 到 1 之间时历史项的权重比一次累加衰减更快近期数据对模型的影响更大r 1 时则强化历史平滑。所以分数阶累加本质上是在控制模型的“记忆衰减速度”。不同 r 对累加序列的影响可以直接归类r 取值累加序列行为适合的原始数据形态0不变换数据本身近似平稳0 ~ 1强化近期权重趋势微变、含局部波动1普通一次累加经典指数增长大于 1深度平滑强指数且噪声较大选择 r 是在保留趋势和抑制噪声之间做平衡。r 过小累加序列很快贴回原始序列递推结果容易被最后几个点带偏r 过大局部拐点被抹平预测变成一条过度平滑的曲线。实际调参时建议把 r 放在 0 到 2 之间搜索而不是凭经验取 0.5 或 1.5。2.3 DGM(1,1) 参数估计的矩阵形式对分数阶累加后的序列 x^(r)长度记为 n递推式 x^(r)(k1) β1 * x^(r)(k) β2 可以写成矩阵形式B [[x^(r)(1), 1], [x^(r)(2), 1], ..., [x^(r)(n-1), 1]]Y [x^(r)(2), x^(r)(3), ..., x^(r)(n)]最小二乘解为β (B^T B)^(-1) B^T Y在实现时我一般直接用numpy.linalg.lstsq避免手写矩阵求逆带来的舍入误差。这个阶段不要加正则化灰色模型的样本量通常不超过 20加 L2 正则会把 β1 压缩向 0导致预测序列退化成常数。预测时从最后一个累加值 x^(r)(n) 开始用递推式逐点外推 h 步得到 x^(r) 的预测序列。最后需要还原到原始量纲采用 r 阶差分算子x^(0)(k) Σ_{j0}^{k-1} (-1)^j * C(r, j) * x^(r)(k - j)当 r 1 时上式就是 x^(r)(k) - x^(r)(k-1)。实现这套计算只需要一个能算实数组合数的函数def comb_real(alpha, m): if m 0: return 1.0 c 1.0 for j in range(1, m 1): c * (alpha - j 1) / j return c这个函数按积形式计算实数二项式系数避免引入 scipy 的依赖。m 是循环次数alpha 是组合数上标。在累加算子中alpha k - i r - 1在差分算子中alpha r。后续所有累加和还原都会复用这个函数。3. 用 Python 实现分数阶累加 DGM从零写起的最小可运行代码3.1 数据准备与累加生成实现分数阶累加生成器。输入是原始一维序列 x输出是 r 阶累加序列。代码里用双重循环直接套定义数据量小的时候完全够用。import numpy as np def frac_accum(x, r): n len(x) y np.empty(n) for k in range(1, n 1): s 0.0 for i in range(1, k 1): m k - i if m 0: c 1.0 else: c comb_real(m r - 1, m) s c * x[i - 1] y[k - 1] s return yx 是 numpy 数组或列表r 是分数阶阶次建议范围 0 到 2。外层循环生成第 k 个累加值内层循环累加所有历史样本。当 k1 时只有 i1 一个项组合数取 1所以累加序列第一个元素总是等于原始序列第一个值这个特性不随 r 改变。3.2 最小二乘估计参数得到累加序列后用最小二乘估计 DGM 参数。这里要说明一下参数含义参数表达式作用β1B 最小二乘解第一项控制上一步累加值对下一步的影响β2B 最小二乘解第二项线性漂移项决定预测曲线的斜率B由累加序列和常数 1 组成递推式里的特征矩阵Y累加序列右移一位递推式的目标向量代码实现def dgm_fit(y): n len(y) B np.column_stack([y[:-1], np.ones(n - 1)]) Y y[1:] beta, _, _, _ np.linalg.lstsq(B, Y, rcondNone) return beta[0], beta[1]y[:-1]取前 n-1 个累加值作为特征第一列np.ones作为第二列。Y是后移一位的累加值也就是要预测的目标。lstsq返回的最小二乘解中beta[0] 是 β1beta[1] 是 β2。rcondNone 表示使用默认的奇异值截断阈值。3.3 预测与累减还原有了 β1 和 β2就能从最后一个累加值出发逐点外推。随后用分数阶差分还原原始序列def frac_diff(y, r): n len(y) out np.empty(n) for k in range(1, n 1): s 0.0 for j in range(k): c (-1) ** j * comb_real(r, j) s c * y[k - 1 - j] out[k - 1] s return out这里的 k 是 1 到 n 的位置索引j 是差分算子中的延迟步数。组合数上标是 r不是m r - 1因为这个差分是累加算子的逆。每一项的符号由 (-1)^j 控制反映差分的交替方向。调用时把累加预测序列和原始累加序列拼接再对整个序列做差分最后取末尾 h 个值就是原始量纲的预测结果。3.4 一份可直接运行的完整代码把上面的函数组合成完整的预测流程def dgm_predict(y, h): b1, b2 dgm_fit(y) last y[-1] pred np.empty(h) for t in range(h): last b1 * last b2 pred[t] last return pred def fdgm_predict(x, r, h1): y frac_accum(x, r) pred dgm_predict(y, h) y_ext np.concatenate([y, pred]) full frac_diff(y_ext, r) return full[-h:]fdgm_predict是面向用户的入口。先对原始序列做分数阶累加再对累加序列做 DGM 外推最后把观测累加值和预测累加值拼接一次性做分数阶差分还原。这样处理的好处是预测点前面的历史累加值不需要额外修正差分公式天然覆盖整个时间轴。注意如果原始序列很短比如少于 5 个点不建议直接使用DGM 的参数估计会变得不稳定。4. 实战分数阶阶次 r 和样本量的调优策略4.1 阶次搜索与模型评价指标最常见的问题是“r 应该取多少”。答案不能靠猜要把 r 当成超参数来搜。搜索范围放在 0 到 2步长取 0.05 或 0.1。评价指标用 MAPE 或 RMSE 都可以但对小样本数据MAPE 更直观并且能避免量纲影响。def mape(actual, pred): actual np.asarray(actual, dtypefloat) pred np.asarray(pred, dtypefloat) return np.mean(np.abs((actual - pred) / actual)) * 100计算 MAPE 时要注意原始序列中是否存在接近 0 的值。如果出现接近 0 的点MAPE 会被放大几个数量级这时候改用 RMSE 或者对称 MAPE。灰色模型常用于能源、经济、设备退化这类正数序列一般不会遇到这个问题。4.2 样本量、异常值对分数阶累加的影响样本量直接影响 r 的可信度。给出一组经验判断样本量建议做法需要注意的风险小于 5不建议用 DGM两个参数拟合三个方程结果随机性太强5 ~ 10r 搜索范围收紧到 0.2 ~ 1.5最优点可能落在一个较宽的高原上10 ~ 30可以放心搜索完整 0 ~ 2用滚动验证确认 r避免过拟合大于 30可以考虑分段或滚动窗口单模型不如时序模型有优势异常值对分数阶累加的影响比普通累加更敏感。r 越小近期权重越大最后一个异常点会被直接放大。如果最后几个点里有明显的离群值先把它们做平滑或修正再进入累加。常见做法是用中位数移动窗口做一次预处理而不是直接把异常值交给最小二乘。4.3 常见误区把 DGM 当 GM 用、盲目选择分数阶第一个误区是在 DGM 里加背景值。DGM 不需要计算 z^(1)有人会把 GM(1,1) 的背景值公式原样搬进来结果参数估计完全走偏。第二个误区是固定 r 为 0.5 或 1。分数阶累加的价值在于让数据自己选择阶次固定 r 等于放弃这个改进。第三个误区是忽略累加序列中第一个点的特殊地位。x^(r)(1) 永远等于 x^(0)(1)调参时不要对这个点做额外缩放。还要注意分数阶累加不是越复杂越好。有些场景下 r 搜索到的最优点会贴到 0说明原始数据已经足够平稳DGM 不再需要累加。这时候改用其他模型可能更合适而不是强行维持灰色模型框架。4.4 用时间序列交叉验证来确认 r确认 r 最可靠的方法是滚动一步预测验证。每个切分点只用前面部分做训练预测下一点然后移动一格重复。这样能模拟真实预测场景避免训练集 MAPE 造成的假象。def cv_single_step(x, r, min_train5): n len(x) errors [] for split in range(min_train, n - 1): train x[:split] test np.array([x[split]]) pred fdgm_predict(train, r, h1) errors.append(abs(pred[0] - test[0]) / max(abs(test[0]), 1e-8)) return np.mean(errors)然后在 r 网格上搜索best_r 1.0 best_score float(inf) for r in np.arange(0, 2.01, 0.05): score cv_single_step(x, r) if score best_score: best_score score best_r rmin_train是训练集最小长度小于它时参数估计不可靠。这里取 5 是经验值数据质量差时提到 8。搜索步长 0.05 足够细继续加密对结果提升很小。最终选出的 best_r 可以直接用于全量数据训练也可以随滚动窗口实时更新。5. 与其它灰色变体的边界判断及一个稳健性检验技巧5.1 什么时候用 DGM 而不是 GM(1,1) 或 Verhulst如果数据呈现明显的指数增长且样本量很短DGM 是最省事的基线。GM(1,1) 适合需要解析解的场景比如需要把预测公式写成指数函数给业务方解释。若数据呈 S 形有饱和趋势应该考虑 Verhulst 灰色模型而不是 DGM。判断方法很简单把原始序列画出来看二阶差分符号是否变化。二阶差分持续同号用 DGM二阶差分出现变号且趋势趋于平缓用 Verhulst。分数阶累加可以叠在 DGM 上也可以叠在 Verhulst 上原理相同。5.2 用残差和灰色关联度做稳健性检验模型选完后除了看误差还要检查预测曲线与真实曲线的形状一致性。灰色关联度是一个合适指标它不等于相关系数更关注曲线变化趋势的几何相似性。def grey_relational_grade(actual, pred): diff np.abs(np.asarray(actual) - np.asarray(pred)) min_d diff.min() max_d diff.max() rho 0.5 rel (min_d rho * max_d) / (diff rho * max_d) return np.mean(rel)关联度接近 1 说明预测曲线在形状层面与真实曲线贴合误差主要集中在幅值上。如果 MAPE 很低但关联度不高说明预测碰到了错位的峰或谷此时可以尝试微调 r。关联度低于 0.7 时模型的实际可用性值得怀疑即使误差指标看起来很漂亮。5.3 最后一个技巧把分数阶累加用在滚动预测里固定 r 只在全量数据一次性预测时有效。在滚动预测中每个周期都会有新数据进来r 的最优值也会变化。比较好的做法是每个时间步重新在 0 到 2 范围里搜索 r并使用最近 N 个点作为训练窗口。这样做开销也不大因为样本量小搜索几十个 r 值只是毫秒级计算。还要给 r 设置一个下界比如 0.1防止搜索到 0 导致累加序列完全等于原始序列失去 DGM 递推的平滑作用。上界可以固定为 2超过 2 后累加权重过大模型会对历史噪声过度记忆。这个滚动更新 r 的做法是分数阶累加 DGM 在工程里最实用的改进能让模型在不改结构的情况下自动适应趋势变化。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门