久违了,前段时间由于学习压力大,就没怎么更新MATLAB相关的内容,今天实在学不进去了,换个内容更新一下~
本贴介绍灰色预测模型,这也是数学建模竞赛常见算法中的一员,和许多预测模型一样——底层原理是根据已知数据对未知进行预测~
一.理论部分 灰色预测是对既含有已知信息又含有不确定信息的系统进行预测,就是对在一定范围内变化的、与时间有关的灰色过程进行预测。 灰色预测对原始数据进行生成处理来寻找系统变动的规律,并生成有较强规律性的数据序列,然后建立相应的微分方程模型,从而预测事物未来发展趋势的状况。 灰色系统理论运用灰色数学处理不确定性量化问题,并充分利用已知信息,寻求系统运动规律。其独特之处在于适用于处理信息匮乏的系统。 灰色生成是通过对原始数据进行特定要求的处理,揭示出数据背后的内在规律。常用的生成方法包括累加生成、累减均值生成和级比生成。所谓的GM(1,1)模型: Grey(Gray) Model,本质上就是一维层面的预测~至于模型更底层复杂的数学原理就不展开详解了,大家自行收集资料,此处主要讲解套路~ 二.例题讲解如下是有关棉花生产的数据:
年份单产种子费化肥费农药费机械费灌溉费kg/公顷元/公顷元/公顷元/公顷元/公顷元/公顷19901017106.05495.15305.145.956.119911036.5113.55561.45343.868.5593.31992792104.55584.8541473.2104.551993861132.75658.35453.7582.95107.551994901.5174.3904.05625.05114152.11995922.5230.41248.75834.45143.85176.41996916.5238.21361.55720.75165.15194.251997976.5260.11337.4727.65201.9291.7519981024.5270.61195.8775.5220.5271.3519991003.5286.21171.8610.95195284.5520001069.5282.91151.55599.85190.65277.3520011168.5317.851105.8553.8211.05290.120021228.5319.651213.05513.75231.6324.1520031023368.41274.1567.45239.85331.820041144.5466.21527.9487.35408336.15 假设我们不知道2005-2007这三年的单产数据,请你用过去15年的数据来预测这三年的产量。 1.传统GM模型的代码 function [result, x0_hat, relative_residuals, eta] = gm11(x0, predict_num)n = length(x0); x1=cumsum(x0); z1 = (x1(1:end-1) + x1(2:end)) / 2; y = x0(2:end); x = z1; k = ((n-1)*sum(x.*y)-sum(x)*sum(y))/((n-1)*sum(x.*x)-sum(x)*sum(x));b = (sum(x.*x)*sum(y)-sum(x)*sum(x.*y))/((n-1)*sum(x.*x)-sum(x)*sum(x));a = -k; x0_hat=zeros(n,1); x0_hat(1)=x0(1);for m = 1: n-1x0_hat(m+1) = (1-exp(a))*(x0(1)-b/a)*exp(-a*m);endresult = zeros(predict_num,1); for i = 1: predict_numresult(i) = (1-exp(a))*(x0(1)-b/a)*exp(-a*(n+i-1)); endabsolute_residuals = x0(2:end) - x0_hat(2:end);relative_residuals = abs(absolute_residuals) ./ x0(2:end); class_ratio = x0(2:end) ./ x0(1:end-1) ; eta = abs(1-(1-0.5*a)/(1+0.5*a)*(1./class_ratio)); end 2.原始数据检验此处选用【单产】作为示例~
year =[1995:1:2001]'; % 横坐标表示年份,写成列向量的形式(加'就表示转置)yield= [10171036.5792861901.5922.5916.5976.51024.51003.51069.51168.51228.510231144.5]'; %原始数据序列,写成列向量的形式(加'就表示转置) ERROR = 0; % 建立一个错误指标,一旦出错就指定为1% 判断是否有负数元素if sum(yield 0 disp('灰色预测的时间序列中不能有负数!')ERROR = 1;end% 判断数据量是否太少n = length(yield); % 计算原始数据的长度disp(strcat('原始数据的长度为',num2str(n)))if n10disp('考虑使用其他的方法')end% 判断数据是否为列向量,如果输入的是行向量则转置为列向量if size(yield,1) == 1yield = yield';endif size(year,1) == 1year = year';end 3.准指数规律检验 if ERROR == 0disp('准指数规律检验')x1 = cumsum(yield); rho = yield(2:end) ./ x1(1:end-1) ;rhofigure(2)plot(year(2:end),rho,'o-',[year(2),year(end)],[0.5,0.5],'-'); grid on;text(year(end-1)+0.2,0.55,'临界线')set(gca,'xtick',year(2:1:end)) xlabel('年份'); ylabel('原始数据的光滑度'); disp(strcat('指标1:光滑比小于0.5的数据占比为',num2str(100*sum(rho