该博客为个人学习清风建模的学习笔记,部分课程可以在B站:【强烈推荐】清风:数学建模算法、编程和写作培训的视频课程以及Matlab等软件教学_哔哩哔哩_bilibili
目录
名称 | 重要性 | 难度 |
预测模型 | ★★★★★ | ★★★★★ |
1灰色预测模型
1.1灰色系统
灰色预测是对既含有已知信息又含有不确定信息的系统进行预测,就是对在一定范围内变化的、与时间有关的灰色过程进行预测。灰色预测对原始数据进行生成处理来寻找系统变动的规律,并生成有较强规律性的数据序列,然后建立相应的微分方程模型,从而预测事物未来发展趋势的状况。
1.2GM(1,1)模型
GM(1,1) 是使用原始的离散非负数据列,通过一次累加生成削弱随机性的较有规律的新的离散数据列,然后通过建立微分方程模型,得到在离散点处的解经过累减生成的原始数据的近似估计值,从而预测原始数据的后续发展。(GM(1,1) 模型,第一个 ‘1’ 表示微分方程是一阶的,后面的‘1’ 表示只有一个变量)
1.2.1GM(1,1)原理介绍
1.2.2OLS原理介绍
矩阵求导: https://blog.csdn.net/lipengcn/article/details/52815429
1.2.3完全多重共线性问题
1.2.4一阶微分方程
1.2.5准指数规律的检验
1.2.6发展系数与预测情形的探究
1.2.7GM(1,1)模型拟合程度残差检验
1.2.8GM(1,1)模型拟合程度级比偏差检验
1.2.9模型拓展
1.3灰色预测模型使用情形
1.4预测题目的套路
(1)看到数据后先画时间序列图并简单的分析下趋势(例如:时间序列分解)时间序列分析: 时间序列分析★★★★-CSDN博客(2)将数据分为训练组和试验组,尝试使用不同的模型对训练组进行建模,并利用试验组的数据判断哪种模型的预测效果最好(比如可以使用SSE这个指标来挑选模型,常见的模型有指数平滑、ARIMA、灰色预测、神经网络等)。(3)选择上一步骤中得到的预测误差最小的那个模型,并利用全部数据来重新建模,并对未来的数据进行预测。(4)画出预测后的数据和原来数据的时序图,看看预测的未来趋势是否合理。
1.5例题
1.5.1代码详解
1. 画出原始数据的时间序列图,并判断原始数据中是否有负数或期数是否低于 4 期,如果是的话则报错,否则执行下一步;2. 对一次累加后的数据进行准指数规律检验,返回两个指标:指标 1 :光滑比小于 0.5 的数据占比(一般要大于 60% )指标 2 :除去前两个时期外,光滑比小于 0.5 的数据占比(一般大于 90% )并让用户决定数据是否满足准指数规律,满足则输入 1 ,不满足则输入 03. 如果上一步用户输入 0 ,则程序停止;如果输入 1 ,则继续下面的步骤。4. 让用户输入需要预测的后续期数,并判断原始数据的期数:4.1 数据期数为 4 :分别计算出传统的GM(1,1) 模型、新信息 GM(1,1) 模型和新陈代谢 GM(1,1) 模型对于未来期数的预测结果,为了保证结果的稳健性,对三个结果求平均值作为预测值。4.2 数据期数为 5,6 或 7 :取最后两期为试验组,前面的n-2 期为训练组;用训练组的数据分别训练三种 GM模型,并将训练出来的模型分别用于预测试验组的两期数据;利用试验组两期的真实数据和预测出来的两期数据,可分别计算出三个模型的SSE ;选择 SSE 最小的模型作为我们建模的模型。4.3 数据期数大于 7 :取最后三期为试验组,其他的过程和4.2 类似。5. 输出并绘制图形显示预测结果,并进行残差检验和级比偏差检验。
1.5.2输入原始数据并画出时间序列图
代码全部摘自清风老师
%% 输入原始数据并做出时间序列图
clear;clc
year =[1995:1:2004]'; % 横坐标表示年份,写成列向量的形式(加'就表示转置)
x0 = [174,179,183,189,207,234,220.5,256,270,285]'; %原始数据序列,写成列向量的形式(加'就表示转置)
% x0=[1017,1036.5,792,861,901.5,922.5,916.5,976.5,1024.5,1003.5,1069.5,1168.5,1228.5,1023,1144.5]';
% year = [2009:2015]; % 其实本程序写成了行向量也可以,因为我怕你们真的这么写了,所以在后面会有判断。
% x0 = [730, 679, 632, 599, 589, 532, 511];
% year = [2010:2017]'; % 该数据很特殊,可以通过准指数规律检验,但是预测效果却很差
% x0 = [1.321,0.387,0.651,0.985,1.235,0.987,0.854,1.021]';
% year = [2014:2017]';
% x0 = [2.874,3.278,3.337,3.390]';
% 画出原始数据的时间序列图
figure(1); % 因为我们的图形不止一个,因此要设置编号
plot(year,x0,'o-'); grid on; % 原式数据的时间序列图
set(gca,'xtick',year(1:1:end)) % 设置x轴横坐标的间隔为1
xlabel('年份'); ylabel('排污总量'); % 给坐标轴加上标签
1.5.3准指数规律检验
disp('准指数规律检验')
x1 = cumsum(x0); % 生成1-AGO序列,cumsum是累加函数哦~ 注意:1.0e+03 *0.1740的意思是科学计数法,即10^3*0.1740 = 174
rho = x0(2:end) ./ x1(1:end-1) ; % 计算光滑度rho(k) = x0(k)/x1(k-1)
% 画出光滑度的图形,并画上0.5的直线,表示临界值
figure(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,'临界线') % 在坐标(year(end-1)+0.2,0.55)上添加文本
set(gca,'xtick',year(2:1:end)) % 设置x轴横坐标的间隔为1
xlabel('年份'); ylabel('原始数据的光滑度'); % 给坐标轴加上标签
disp(strcat('指标1:光滑比小于0.5的数据占比为',num2str(100*sum(rho<0.5)/(n-1)),'%'))
disp(strcat('指标2:除去前两个时期外,光滑比小于0.5的数据占比为',num2str(100*sum(rho(3:end)<0.5)/(n-3)),'%'))
disp('参考标准:指标1一般要大于60%, 指标2要大于90%,你认为本例数据可以通过检验吗?')
Judge = input('你认为可以通过准指数规律的检验吗?可以通过请输入1,不能请输入0:');
1.5.4传统GM(1,1)模型
function [result, x0_hat, relative_residuals, eta] = gm11(x0, predict_num)
% 函数作用:使用传统的GM(1,1)模型对数据进行预测
% x0:要预测的原始数据
% predict_num: 向后预测的期数
% 输出变量 (注意,实际调用时该函数时不一定输出全部结果,就像corrcoef函数一样~,可以只输出相关系数矩阵,也可以附带输出p值矩阵)
% result:预测值
% x0_hat:对原始数据的拟合值
% relative_residuals: 对模型进行评价时计算得到的相对残差
% eta: 对模型进行评价时计算得到的级比偏差
n = length(x0); % 数据的长度
x1=cumsum(x0); % 计算一次累加值
z1 = (x1(1:end-1) + x1(2:end)) / 2; % 计算紧邻均值生成数列(长度为n-1)
% 将从第二项开始的x0当成y,z1当成x,来进行一元回归 y = kx +b
y = x0(2:end); x = z1;
% 下面的表达式就是第四讲拟合里面的哦~ 但是要注意,此时的样本数应该是n-1,少了一项哦
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; %注意:k = -a哦
% 注意: -a就是发展系数, b就是灰作用量
disp('现在进行GM(1,1)预测的原始数据是: ')
disp(mat2str(x0')) % mat2str可以将矩阵或者向量转换为字符串显示
disp(strcat('最小二乘法拟合得到的发展系数为',num2str(-a),',灰作用量是',num2str(b)))
disp('***************分割线***************')
x0_hat=zeros(n,1); x0_hat(1)=x0(1); % x0_hat向量用来存储对x0序列的拟合值,这里先进行初始化
for m = 1: n-1
x0_hat(m+1) = (1-exp(a))*(x0(1)-b/a)*exp(-a*m);
end
result = zeros(predict_num,1); % 初始化用来保存预测值的向量
for i = 1: predict_num
result(i) = (1-exp(a))*(x0(1)-b/a)*exp(-a*(n+i-1)); % 带入公式直接计算
end
% 计算绝对残差和相对残差
absolute_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) ; % 计算级比 sigma(k) = x0(k)/x0(k-1)
eta = abs(1-(1-0.5*a)/(1+0.5*a)*(1./class_ratio)); % 计算级比偏差
end
1.5.5新信息GM(1,1)模型
function [result] = new_gm11(x0, predict_num)
% 函数作用:使用新信息的GM(1,1)模型对数据进行预测
% 输入变量
% x0:要预测的原始数据
% predict_num: 向后预测的期数
% 输出变量
% result:预测值
result = zeros(predict_num,1); % 初始化用来保存预测值的向量
for i = 1 : predict_num
result(i) = gm11(x0, 1); % 将预测一期的结果保存到result中
x0 = [x0; result(i)]; % 更新x0向量,此时x0多了新的预测信息
end
end
1.5.6新陈代谢GM(1,1)模型
function [result] = metabolism_gm11(x0, predict_num)
% 函数作用:使用新陈代谢的GM(1,1)模型对数据进行预测
% 输入变量
% x0:要预测的原始数据
% predict_num: 向后预测的期数
% 输出变量
% result:预测值
result = zeros(predict_num,1); % 初始化用来保存预测值的向量
for i = 1 : predict_num
result(i) = gm11(x0, 1); % 将预测一期的结果保存到result中
x0 = [x0(2:end); result(i)]; % 更新x0向量,此时x0多了新的预测信息,并且删除了最开始的那个向量
end
end
2神经网络预测
2.1原理
原理的视频介绍(只看前 20 分钟,后面的讲的不怎么好,可跳过)https://www.bilibili.com/video/av53675526/神经网络原理的简单介绍: https://blog.csdn.net/weixin_40432828/article/details/82192709神经网络的应用: https://blog.csdn.net/houshaolin/article/details/74240017
2.2机器学习
训练集( Training set ) —— 用于模型拟合的数据样本。验证集( Validation set ) —— 是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估。在神经网络中,我们用验证数据集去寻找最优的网络深度,或者决定反向传播算法的停止点或者在神经网络中选择隐藏层神经元的数量;测试集( Testing set ) —— 用来评估模最终模型的泛化能力。但不能作为调参、选择特征等算法相关的选择的依据。一个形象的比喻:训练集 ----------- 学生的课本;学生根据课本里的内容来掌握知识。验证集 ------------ 作业,通过作业可以知道不同学生学习情况、进步的速度快慢。测试集 ----------- 考试,考的题是平常都没有见过,考察学生举一反三的能力。其他博文:https://blog.csdn.net/liushiqi0826/article/details/86514585
2.3例题-辛烷值预测
【改编】辛烷值是汽油最重要的品质指标,传统的实验室检测方法存在样品用量大,测试周期长和费用高等问题,不适用于生产控制,特别是在线测试。近年发展起来的近红外光谱分析方法(NIR ),作为一种快速分析方法,已广泛应用于农业、制药、生物化工、石油产品等领域。其优越性是无损检测、低成本、无污染,能在线分析,更适合于生产和控制的需要。实验采集得到50 组汽油样品(辛烷值已通过其他方法测量),并利用傅里叶近红外变换光谱仪对其进行扫描,扫描范围900~1700nm ,扫描间隔为 2nm ,即每个样品的光谱曲线共含401 个波长点,每个波长点对应一个吸光度。( 1 )请利用这 50 组样品的数据,建立这 401 个吸光度和辛烷值之间的模型。( 2 )现给你 10 组新的样本,这 10 组样本均已经过近红外变换光谱仪扫描,请预测这10 组新样本的辛烷值。
2.3.1数据导入
在工作区新建好上述三个变量后,我们将Excel的数据分别粘贴到变量中,然后在Matlab的工作区内按快捷键“Ctrl+S”(或者鼠标右键点击保存也可以),就可以将数据文件保存在本地。下次使用时,只需要将数据加载到Matlab即可。
加载数据使用 load 命令,代码、文件以及当前 Matlab 的工作路径需要在同一个文件夹。
2.3.2打开神经网络拟合工具箱
博主的MATLAB版本是2021b。
2.3.3工具箱中导入数据
2.3.4设置数据占比和隐层神经元个数
2.3.5选择算法开始训练
莱文贝格-马夸特方法 ( Levenberg–Marquardt algorithm )能提供数非线性最小化(局部最小)的数值解。此算法能借由执行时修改参数达到结合高斯- 牛顿算法以及梯度下降法的优点,并对两者之不足作改善(比如高斯- 牛顿算法之反矩阵不存在或是初始值离局部极小值太远)贝叶斯正则化方法 ( Bayesian-regularization ):https://blog.csdn.net/sinat_38835380/article/details/86927943量化共轭梯度法 ( Scaled Conjugate Gradient ):《模式识别与智能计算 ——MATLAB 技术实现》
2.3.6查看结果
算法使用的是莱文贝格-马夸特方法:
(1)训练状态
(2)性能
epoch : 1 个 epoch 等于使用训练集中的全部样本训练一次,每训练一次,神经网络中的参数经过调整。 MSE: Mean Squared Error 均方误差 MSE = SSE/n一般来说,经过更多的训练阶段后,误差会减小,但随着网络开始过度拟合训练数据,验证数据集的误差可能会开始增加。在默认设置中,在验证数据集的MSE 连续增加六次后,训练停止,最佳模型对应于的最小的MSE。
(3)误差直方图
(4)回归
将拟合值对真实值回归,拟合优度越高,说明拟合的的效果越好。
2.4.7导出结果
(1)导出代码
(2)导出结果
2.4.8进行预测
% 这里要注意,我们要将指标变为列向量,然后再用sim函数预测
sim(results.Network, new_X(1,:)')
%
% 写一个循环,预测接下来的十个样本的辛烷值
predict_y = zeros(10,1); % 初始化predict_y
for i = 1: 10
result = sim(results.Network, new_X(i,:)');
predict_y(i) = result;
end
disp('预测值为:')
disp(predict_y)
3总结
神经网络预测的优点在于其强大的学习能力和处理非线性关系的能力,能够从大量数据中提取特征并建模,特别适用于图像识别、自然语言处理等复杂问题。然而,其缺点也显而易见,如对数据的需求量大,训练成本高,且模型结构复杂,解释性差,难以直接解释预测结果的依据。
灰色预测则适用于数据量较少、信息不完整或可靠性较低的情况。其优点在于建模所需信息少,运算简便,易于检验,且能较好地挖掘数据的本质,进行中短期预测时精度较高。然而,灰色预测也有其局限性,如主要适用于中短期预测和指数增长的预测,对于长期或复杂系统的预测效果可能不佳。