ARTICLE DETAIL

资讯详情

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

MATLAB实现灰色预测GM(1,1)模型:小样本数据预测实战指南

MATLAB实现灰色预测GM(1,1)模型:小样本数据预测实战指南 1. 从“拍脑袋”到“算数据”为什么我们需要灰色预测在数据分析、项目规划甚至日常决策中我们常常面临一个尴尬的局面手头的数据少得可怜。可能只有寥寥几年的销售记录几个季度的用户增长数据或者几组不完整的实验观测值。这时候传统的统计预测方法比如回归分析、时间序列分析ARIMA往往会因为数据量不足、样本分布不满足假设而“哑火”或者得出一个置信区间大到毫无意义的结论。我们总不能每次都靠“拍脑袋”或者“凭经验”来做重要预测吧灰色预测就是为解决这种“小样本、贫信息”的不确定性系统预测问题而生的。它不像传统方法那样追求大样本和典型的概率分布而是另辟蹊径通过对少量、不完全信息的挖掘、加工和延伸来揭示系统内在的规律并进行预测。其核心思想非常巧妙任何随机过程都是在一定幅值范围、一定时区内变化的灰色量我们把随机过程看作灰色过程。通过对原始数据序列进行累加生成弱化其随机性挖掘出潜在的指数增长趋势然后用一个简单的微分方程模型即GM(1,1)模型去拟合这个趋势最后再通过累减还原得到预测值。听起来有点抽象举个例子假设你是一家初创公司的产品经理手头只有产品上线后前5个月的日活用户数据[100, 130, 170, 220, 290]。你想预测下个月的数据。用回归分析数据点太少线性或非线性拟合都不太靠谱。用时间序列至少需要几十个数据点来建模。这时候灰色预测GM(1,1)模型就能派上用场。它不关心数据背后的复杂影响因素只专注于数据序列本身呈现出的“态势”非常适合这种数据稀缺但趋势初显的场景。而MATLAB作为强大的数值计算和算法实现平台为我们快速、准确、可视化地实现灰色预测提供了绝佳的工具箱。本文将手把手带你深入灰色预测的原理并用MATLAB从零实现一个稳健、可靠的预测流程分享我在实际应用中踩过的坑和总结的经验。2. 灰色预测GM(1,1)模型剥开数学外壳看本质灰色预测模型家族中有多个成员但最基础、应用最广泛的是GM(1,1)模型。这里的G代表Grey灰色M代表Model模型第一个1表示一阶方程第二个1表示一个变量。它本质上是一个单变量的一阶微分方程模型。理解它的关键在于三个步骤累加生成、模型建立、累减还原。我们不用被数学符号吓倒我会用最直白的方式和前面的例子数据来解释。2.1 累加生成从“跳动的音符”到“平滑的曲线”原始数据序列往往波动较大显得杂乱无章我们称之为原始序列。记作 \( X^{(0)} (x^{(0)}(1), x^{(0)}(2), ..., x^{(0)}(n)) \) 在我们的例子里\( X^{(0)} (100, 130, 170, 220, 290) \)。累加生成Accumulated Generating Operation, AGO是灰色预测的“魔法”第一步。它的操作很简单把序列中第一个数到当前数的所有值加起来生成一个新序列。这样做的目的是弱化原始数据的随机性和波动性强化其内在的指数增长趋势。生成的新序列叫一次累加生成序列记作 \( X^{(1)} \) \( x^{(1)}(k) \sum_{i1}^{k} x^{(0)}(i), \quad k1,2,...,n \)我们来手动算一下\( x^{(1)}(1) x^{(0)}(1) 100 \)\( x^{(1)}(2) x^{(0)}(1) x^{(0)}(2) 100 130 230 \)\( x^{(1)}(3) x^{(0)}(1)x^{(0)}(2)x^{(0)}(3) 100130170400 \)\( x^{(1)}(4) 100130170220 620 \)\( x^{(1)}(5) 100130170220290 910 \)所以\( X^{(1)} (100, 230, 400, 620, 910) \)。你可以直观地感受到原来波动增长的数据100-130-170...经过累加后变成了一个更平滑、增长更稳定的序列。这就像把一段崎岖的山路原始序列的海拔累积起来得到的是从起点开始的总爬升高度累加序列后者显然更容易用一条光滑的曲线来拟合。2.2 构建灰微分方程找到驱动增长的“引擎”对于光滑的累加序列 \( X^{(1)} \)灰色系统理论认为它可以近似地用下面这个一阶常微分方程来描述 \( \frac{dx^{(1)}}{dt} ax^{(1)} b \) 这就是GM(1,1)模型的白化方程影子方程。其中\( a \) 称为发展系数它反映了序列 \( X^{(1)} \) 的发展态势\( b \) 称为灰色作用量可以理解为系统内的内生驱动力量。但是我们处理的是离散数据不是连续函数。所以需要将其离散化得到灰微分方程 \( x^{(0)}(k) az^{(1)}(k) b \) 这里出现了一个新东西\( z^{(1)}(k) \)。它被称为背景值通常取为紧邻均值的生成 \( z^{(1)}(k) 0.5x^{(1)}(k) 0.5x^{(1)}(k-1) \), \( k2,3,...,n \)为什么是0.5这其实是一种梯形公式近似用相邻两点的均值来代表这个区间内的“背景水平”是工程上的一种常用处理实践证明效果很好。当然背景值的构造是灰色预测的一个研究热点也有其他加权方式但0.5加权是最经典和稳健的。对于我们的例子我们可以计算背景值序列 \( Z^{(1)} \)\( z^{(1)}(2) 0.5100 0.5230 165 \)\( z^{(1)}(3) 0.5230 0.5400 315 \)\( z^{(1)}(4) 0.5400 0.5620 510 \)\( z^{(1)}(5) 0.5620 0.5910 765 \)现在对于每一个 \( k2,3,4,5 \)我们都有一个方程 \( x^{(0)}(k) a \cdot z^{(1)}(k) b \) 把数据代进去k2: 130 a*165 bk3: 170 a*315 bk4: 220 a*510 bk5: 290 a*765 b这里有4个方程但只有两个未知数 \( a \) 和 \( b \)显然这是一个超定方程组通常无精确解。所以我们需要用最小二乘法来求取最优的参数 \( a \) 和 \( b \)。2.3 最小二乘求解与时间响应式拿到预测公式将上面的方程组写成矩阵形式 \( Y B \cdot \hat{u} \) 其中 \( Y \begin{bmatrix} x^{(0)}(2) \\ x^{(0)}(3) \\ x^{(0)}(4) \\ x^{(0)}(5) \end{bmatrix} \begin{bmatrix} 130 \\ 170 \\ 220 \\ 290 \end{bmatrix} \) \( B \begin{bmatrix} -z^{(1)}(2) 1 \\ -z^{(1)}(3) 1 \\ -z^{(1)}(4) 1 \\ -z^{(1)}(5) 1 \end{bmatrix} \begin{bmatrix} -165 1 \\ -315 1 \\ -510 1 \\ -765 1 \end{bmatrix} \) 待求参数向量 \( \hat{u} \begin{bmatrix} a \\ b \end{bmatrix} \)。根据最小二乘法参数的最优估计为 \( \hat{u} (B^T B)^{-1} B^T Y \) 这个计算过程交给MATLAB再合适不过了我们后面会具体实现。求出 \( a \) 和 \( b \) 后代入回白化方程 \( \frac{dx^{(1)}}{dt} ax^{(1)} b \)并假设初始条件 \( \hat{x}^{(1)}(1) x^{(0)}(1) \)可以解出这个微分方程得到累加序列的时间响应式即预测函数 \( \hat{x}^{(1)}(k1) \left( x^{(0)}(1) - \frac{b}{a} \right) e^{-ak} \frac{b}{a} \), \( k0,1,2,... \)这个公式非常重要它告诉我们拟合出的累加序列 \( X^{(1)} \) 遵循一个指数增长当a为负时或衰减当a为正时的规律。2.4 累减还原从“总爬升”回到“每一步”我们最终要预测的是原始序列而不是累加序列。所以需要对预测的累加序列进行累减生成Inverse AGO, IAGO也就是求差分 \( \hat{x}^{(0)}(k1) \hat{x}^{(1)}(k1) - \hat{x}^{(1)}(k) \), \( k1,2,... \) 特别地\( \hat{x}^{(0)}(1) \hat{x}^{(1)}(1) x^{(0)}(1) \)。将时间响应式代入可以得到原始序列的预测公式 \( \hat{x}^{(0)}(k1) (1-e^{a}) \left( x^{(0)}(1) - \frac{b}{a} \right) e^{-ak} \), \( k1,2,... \)至此我们拿到了最终的预测“武器”。只要有了参数 \( a \) 和 \( b \)就能预测未来任意时刻的值。整个逻辑链条是原始数据 → 累加生成平滑化→ 建立灰微分方程 → 最小二乘估计参数 → 得到累加序列预测式 → 累减还原得到最终预测值。3. MATLAB实战从零手搓一个稳健的灰色预测函数理解了原理我们就在MATLAB里把它实现出来。我将带你编写一个功能完整、带有检验和可视化功能的灰色预测函数。这个过程我会详细解释每一行代码的意图并分享我调试过程中遇到的典型问题。3.1 核心函数编写my_gm11我们不直接使用可能存在的模糊工具箱函数而是自己实现这样理解更深刻可控性也更强。function [predict, a, b, C, P, fit_error] my_gm11(data, predict_num) % MY_GM11 灰色预测GM(1,1)模型实现 % 输入 % data: 原始数据序列行向量或列向量例如 [100; 130; 170; 220; 290] % predict_num: 需要预测的未来期数例如预测后2期则输入2 % 输出 % predict: 预测值包括历史拟合值和未来预测值长度 length(data) predict_num % a: 发展系数 % b: 灰色作用量 % C: 后验差比 % P: 小误差概率 % fit_error: 历史数据拟合相对误差百分比向量 % 输入检查与预处理 if nargin 2 predict_num 0; % 默认只拟合不预测未来 end data data(:); % 确保数据是列向量 n length(data); if n 4 error(灰色预测至少需要4个数据点。); end % 1. 累加生成(AGO) data_cum cumsum(data); % cumsum函数直接实现累加 % 2. 构造数据矩阵B和Y % 计算背景值z (k2到n) z 0.5 * (data_cum(1:n-1) data_cum(2:n)); B [-z, ones(n-1, 1)]; % 构造B矩阵 Y data(2:n); % 构造Y向量 % 3. 最小二乘法求解参数 a, b % 使用pinv求广义逆比inv更稳定尤其当B*B接近奇异时 u pinv(B * B) * B * Y; a u(1); b u(2); % 4. 计算历史拟合值 % 时间响应式: \hat{x}^{(1)}(k1) (data(1)-b/a)*exp(-a*k) b/a k 0:(n-1); % 时间序列从0开始 fit_cum (data(1) - b/a) * exp(-a * k) b/a; % 累加序列拟合值 % 累减还原(IAGO)得到原始序列拟合值 fit [fit_cum(1); fit_cum(2:end) - fit_cum(1:end-1)]; % 5. 计算未来预测值如果需要 future_k n:(n predict_num - 1); % 未来时刻对应的k future_cum (data(1) - b/a) * exp(-a * future_k) b/a; future future_cum - [fit_cum(end); future_cum(1:end-1)]; % 注意这里的差分 predict [fit; future]; % 合并历史拟合与未来预测 % 6. 模型检验计算后验差比C和小误差概率P % 残差 residual data - fit(1:n); % 只计算历史期的残差 % 原始数据均值与方差 mean_data mean(data); S1 std(data); % 残差均值与方差 mean_residual mean(residual); S2 std(residual); % 后验差比 C S2 / S1; % 计算小误差概率 % 计算每个残差与均值的绝对偏差 delta abs(residual - mean_residual); % 计算0.6745 * S1 threshold 0.6745 * S1; % 统计绝对偏差小于阈值的点数 P sum(delta threshold) / n; % 7. 计算拟合相对误差 fit_error abs(residual) ./ data * 100; % 百分比误差 end代码要点与避坑指南cumsum函数这是实现累加生成最简洁高效的方法避免了写循环。背景值构造z 0.5 * (data_cum(1:n-1) data_cum(2:n))这行代码优雅地实现了背景值序列的计算利用了MATLAB的向量化操作。pinvvsinv在求解最小二乘参数u (B*B) \ (B*Y)时我选择了使用伪逆pinv。为什么因为当数据序列特性不好例如增长非常缓慢时B*B可能接近奇异矩阵使用inv或反斜杠运算符\会得到不稳定的结果甚至报错。pinv基于奇异值分解能提供更稳健的解这是实践中提高代码鲁棒性的一个小技巧。时间响应式的向量化计算exp(-a * k)这里利用矩阵运算一次性计算出所有时间点的指数项比用循环快得多。未来预测的差分future future_cum - [fit_cum(end); future_cum(1:end-1)];这行是关键。future_cum是未来时刻的累加预测值。要得到原始序列的预测值需要用当前累加值减去前一个累加值。[fit_cum(end); future_cum(1:end-1)]这个向量构造得非常巧妙它的第一个元素是最后一个历史拟合累加值fit_cum(end)后续元素是未来预测累加值序列的前移。这样一减就正确得到了未来第一期、第二期...的预测值。模型检验后验差比C和小误差概率P是评价灰色预测模型精度等级的经典指标。通常C越小越好P越大越好。具体的精度等级对照表我们会在后面详细讨论。计算P时阈值0.6745 * S1是一个经验常数来源于概率统计。3.2 可视化与结果分析脚本一个只有数字输出的函数是不完整的。我们需要直观地看到拟合效果和预测趋势。下面是一个配套的脚本示例%% 灰色预测GM(1,1)实战演示 clear; clc; close all; % 1. 准备数据使用之前的例子 original_data [100, 130, 170, 220, 290]; predict_steps 3; % 预测未来3期 % 2. 调用灰色预测函数 [predict, a, b, C, P, fit_error] my_gm11(original_data, predict_steps); % 3. 打印关键结果 fprintf( GM(1,1)模型参数与检验 \n); fprintf(发展系数 a %.6f\n, a); fprintf(灰色作用量 b %.6f\n, b); fprintf(后验差比 C %.6f\n, C); fprintf(小误差概率 P %.6f\n, P); fprintf(----------------------------------------\n); fprintf(序号\t原始值\t拟合值\t相对误差(%%)\n); for i 1:length(original_data) fprintf(%d\t%.2f\t%.2f\t%.2f\n, i, original_data(i), predict(i), fit_error(i)); end fprintf(----------------------------------------\n); fprintf(未来%d期预测值\n, predict_steps); for i 1:predict_steps fprintf(第%d期: %.2f\n, length(original_data)i, predict(length(original_data)i)); end % 4. 模型精度等级判断 fprintf( 模型精度评价 \n); if (C 0.35) (P 0.95) grade 优秀 (1级); elseif (C 0.5) (P 0.8) grade 合格 (2级); elseif (C 0.65) (P 0.7) grade 勉强合格 (3级); else grade 不合格 (4级); end fprintf(模型精度等级: %s\n, grade); fprintf((参考标准C越小越好P越大越好)\n); % 5. 绘制对比图 figure(Position, [100, 100, 1200, 500]); % 子图1原始值与拟合/预测值对比 subplot(1,2,1); n_original length(original_data); n_total length(predict); x_hist 1:n_original; x_future (n_original1):n_total; plot(x_hist, original_data, bo-, LineWidth, 2, MarkerSize, 8, DisplayName, 原始数据); hold on; plot(x_hist, predict(1:n_original), rs--, LineWidth, 1.5, MarkerSize, 6, DisplayName, 历史拟合); plot(x_future, predict(n_original1:end), g^--, LineWidth, 1.5, MarkerSize, 8, DisplayName, 未来预测); grid on; xlabel(时间序列); ylabel(数值); title(sprintf(灰色预测GM(1,1)结果 (a%.4f, b%.4f), a, b)); legend(Location, best); % 添加文本标注 for i 1:n_original text(x_hist(i), original_data(i), sprintf( %.1f, original_data(i)), VerticalAlignment, bottom); text(x_hist(i), predict(i), sprintf( %.1f, predict(i)), VerticalAlignment, top, Color, r); end for i 1:predict_steps text(x_future(i), predict(n_originali), sprintf( %.1f, predict(n_originali)), VerticalAlignment, bottom, Color, g); end % 子图2拟合相对误差条形图 subplot(1,2,2); bar(x_hist, fit_error, FaceColor, [0.85 0.33 0.10]); hold on; plot(xlim, [10 10], r--, LineWidth, 1.5, DisplayName, 10%误差线); % 常用误差参考线 grid on; xlabel(时间序列); ylabel(相对误差 (%)); title(历史数据拟合相对误差); legend; % 在柱子上方标注误差值 for i 1:n_original text(x_hist(i), fit_error(i), sprintf(%.2f%%, fit_error(i)), ... HorizontalAlignment, center, VerticalAlignment, bottom, FontSize, 9); end运行这个脚本你会得到详细的数值输出和两张直观的图表。第一张图将原始数据、历史拟合值和未来预测值画在一起让你一眼看清模型的拟合效果和预测趋势。第二张图是每个历史数据点的拟合相对误差帮助你快速定位哪些点拟合得不好。注意在绘制预测部分绿色三角虚线时一定要明确这只是模型的趋势外推。灰色预测适用于短期预测对于长期预测误差会因模型假设的局限性而迅速放大。图中绿色的预测线其意义在于展示“如果系统保持当前挖掘出的指数规律发展未来可能会怎样”而非精确的预言。4. 模型检验你的预测结果靠谱吗模型建好了预测值也出来了但我们不能盲目相信这些数字。必须对模型进行检验评估其精度和可靠性。灰色预测常用的检验方法有残差检验、后验差检验和关联度检验。在我们的函数中主要实现了后验差检验因为它能给出一个综合性的评价等级。4.1 后验差检验C与P的解读后验差检验的核心是两个指标后验差比C和小误差概率P。后验差比 C\( C \frac{S_2}{S_1} \)其中 \( S_1 \) 是原始数据的标准差\( S_2 \) 是残差的标准差。C越小说明残差的波动相对于原始数据的波动越小即预测值与实际值之间的差异越“稳定”模型精度越高。小误差概率 P\( P P{ |\epsilon(k) - \bar{\epsilon}| 0.6745 S_1 } \)。其中 \( \epsilon(k) \) 是各点残差\( \bar{\epsilon} \) 是残差均值。这个指标衡量的是残差分布是否集中。P越大说明残差与残差均值的偏差大部分都落在一个较窄的范围内由0.6745 * S1界定模型预测的“一致性”越好。根据C和P的值可以将模型精度分为四个等级模型精度等级后验差比 C小误差概率 P优秀 (1级)C 0.35P 0.95合格 (2级)C 0.50P 0.80勉强合格 (3级)C 0.65P 0.70不合格 (4级)C ≥ 0.65P ≤ 0.70在我们的例子中计算出的C通常很小因为数据趋势明显P通常为1模型等级为“优秀”。但这并不意味着模型万能这个评价是基于历史拟合的。对于预测的未来值我们还需要结合业务逻辑进行判断。4.2 残差检验与关联度分析进阶除了后验差检验我们还可以手动进行更细致的分析残差序列分析计算每个历史点的绝对误差和相对误差我们的函数已输出。观察误差是否随机分布。如果误差呈现明显的趋势例如前期负、后期正说明模型可能没有完全捕捉到数据的变化模式或者数据本身不适合用GM(1,1)模型。% 计算并绘制残差序列 residual original_data - predict(1:length(original_data)); figure; plot(1:length(residual), residual, o-); hold on; plot(xlim, [0 0], k--); % 零基准线 xlabel(序列点); ylabel(残差); title(模型残差序列图); grid on;一个理想的残差图应该围绕零线随机上下波动无规律可循。关联度分析关联度用于分析模型曲线与原始数据曲线在几何形状上的相似程度。计算略复杂但思路是比较两条曲线在各个时间点上的“距离”经过变换后得到一个介于0和1之间的数越接近1说明形状越相似。对于要求极高的场景可以补充计算关联度r通常要求r 0.6。实操心得在实际项目中我通常将后验差检验作为“快速体检”只要达到“合格”以上就认为模型在历史数据上是可用的。然后我一定会把残差图拿出来仔细看。如果残差图看起来有规律我会非常警惕可能会考虑对原始数据进行平移或方根变换等预处理。使用GM(1,1)的改进模型如GM(1,1)幂模型。或者直接结论该数据集不适合使用标准的GM(1,1)模型。5. 避坑指南与实战经验那些教科书上不会告诉你的细节灰色预测原理简单但在实际应用中稍不注意就会得到离谱的结果。下面是我在多次实践中总结出的关键注意事项和技巧。5.1 数据预处理不是所有序列都叫“光滑序列”GM(1,1)模型要求原始序列是“准光滑序列”即满足 \( \frac{x^{(0)}(k)}{x^{(1)}(k-1)} \) 的比值随k增大而递减且小于某个阈值。但现实数据往往不那么“听话”。负值或零值问题这是GM(1,1)的一个经典禁忌。因为模型的核心是指数拟合如果原始数据有非正数零或负值在累加生成和指数运算中会导致计算问题或失去意义。解决方法是进行“平移变换”给所有数据加上一个常数c使得最小数据大于0。即data_new data_original c其中c abs(min(data_original)) δδ是一个小的正数如0.1或1视数据量级而定。预测完成后再从结果中减去这个常数c。注意这个操作会改变数据的增长基准对预测趋势的斜率发展系数a有轻微影响但通常是可接受的。% 数据平移处理示例 original_data [ -5, 2, 10, 18, 25]; % 包含负值 c abs(min(original_data)) 1; % 平移常数 data_processed original_data c; % 对 data_processed 进行灰色预测 % ... 预测得到 predict_processed predict_final predict_processed - c; % 最终预测结果数据震荡剧烈如果原始数据上下跳动很大没有明显的增长或衰减趋势强行使用GM(1,1)效果会很差。此时后验差比C会很大残差图也很难看。这种情况下灰色预测可能不是合适的工具应考虑其他方法或先对数据进行平滑处理如移动平均。数据量级差异巨大如果序列中同时存在像0.01和1000这样的数据计算时可能会带来数值不稳定。可以考虑先取对数如果数据全为正进行压缩预测后再指数还原。但这会改变模型结构从预测指数增长变为预测对数线性增长需根据实际物理意义决定。5.2 预测期数切忌“一眼万年”GM(1,1)模型基于“指数规律不变”的假设进行外推。在短期内系统惯性可能使得这个假设近似成立。但长期来看任何系统的增长都会遇到瓶颈S型曲线或者外部条件会发生改变。因此灰色预测通常只适用于短期预测。经验法则预测期数最好不要超过原始数据序列长度的一半。例如你有10期历史数据最多预测未来5期。对于我们的5期数据例子预测2-3期是相对合理的预测5期以上就需要非常谨慎并必须结合业务背景进行研判。滚动预测对于需要做长期预测的场景更好的方法是采用“滚动预测”。即用最初的数据预测下一期然后将这一期的真实值或预测值如果无法获得真实值加入历史序列剔除最早的一期数据用这个新的序列重新建立GM(1,1)模型再预测下一期。如此反复不断用最新的信息更新模型。这能在一定程度上适应系统规律的变化。5.3 发展系数a的符号揭示系统本质参数a的符号和大小包含了重要信息a 0这是最常见的情况表示系统呈现指数增长趋势。|a|越大增长越快。a 0表示系统呈现指数衰减趋势。a ≈ 0这是一个需要警惕的信号。如果a的绝对值非常接近0例如小于1e-3说明数据序列几乎没有指数趋势更接近线性。此时GM(1,1)模型会退化为近似线性模型预测可能不稳定精度检验也往往通不过。这时应该考虑是否改用线性回归。在我的函数输出中务必关注a的值。如果得到一个接近0的a首先要检查数据其次要怀疑模型适用性。5.4 与MATLAB工具箱函数的对比与选择MATLAB的模糊逻辑工具箱Fuzzy Logic Toolbox里其实自带了一个gm11函数在较早版本中R2010b左右。如果你有该工具箱可以对比一下结果。但据我的经验自己实现的函数有以下几个优势透明可控每一行代码你都清楚在做什么参数检验、误差计算方式完全由你定义。可定制性强你可以轻松修改背景值公式例如尝试其他权重、添加新的检验指标、或者集成数据预处理步骤。避免依赖无需安装额外的工具箱代码可移植性高。自己实现的核心函数my_gm11在大多数情况下的计算结果与官方函数gm11是一致的但在数据边界条件处理上可能更符合你的特定需求。5.5 一个综合案例能源消耗预测假设我们有某企业2019-2023年的年度能耗数据单位万吨标准煤[8.5, 9.2, 10.1, 11.3, 12.7]。我们需要预测2024年和2025年的能耗。% 综合案例能源消耗预测 energy [8.5, 9.2, 10.1, 11.3, 12.7]; steps 2; [pred, a, b, C, P, err] my_gm11(energy, steps); fprintf(能源消耗预测模型\n); fprintf(发展系数 a %.4f (负值表明能耗呈增长趋势)\n, a); fprintf(模型精度: C%.4f, P%.4f, 等级: , C, P); % ... 精度判断代码 fprintf(2024年预测能耗: %.2f 万吨标准煤\n, pred(6)); fprintf(2025年预测能耗: %.2f 万吨标准煤\n, pred(7)); fprintf(平均年增长率(基于模型): %.2f%%\n, (exp(-a)-1)*100);运行后你可能会得到a ≈ -0.12预测2024年能耗约14.32025年约16.1。模型精度很可能为优秀。但作为分析师你不能只报数字。你需要指出该预测基于过去5年能耗保持当前指数增长规律的假设。实际中需考虑节能技术改造、生产规模变化等因素此预测值可作为基准情景建议结合定性分析进行修正。这种将定量模型结果与定性业务分析结合的表述才是灰色预测价值最大化的体现。灰色预测是一个强大而灵活的工具特别适合在数据匮乏的初期进行趋势研判。通过MATLAB实现我们不仅能快速得到预测值更能通过可视化和模型检验深入理解预测结果的可信度与局限性。记住没有哪个模型是银弹GM(1,1)的简洁既是其优势也决定了其边界。在实际工作中将其作为分析工具箱中的一件利器结合业务常识和其他模型结论才能做出更负责任的决策。
返回列表