基于BP神经网络的多输入单输出回归预测模型简介
该模型使用了BP神经网络Backpropagation Neural Network进行多输入单输出的回归预测。BP神经网络是一种常见的多层前馈神经网络,通过反向传播算法来优化权重和偏置,从而最小化预测误差。
具体模型原理就不再细说了,需要可以翻看我主页另外的BP会有详细一点的过程!
以下是对该模型及其代码的部分解读:
模型原理概述
BP神经网络是一种前馈型神经网络,具有输入层、隐藏层和输出层。该网络通过逐层的信号传播来进行预测,并通过反向传播算法(BP算法)来更新权重和偏置,使预测误差最小化。在回归预测任务中,BP神经网络通过学习输入特征与目标变量之间的映射关系,从而实现对连续性输出的预测。
模型结构
- 输入层:接受多个输入特征,在本代码中包含若干特征变量。
- 隐藏层:用于捕捉数据的非线性关系,神经元个数由
hiddens
参数控制。本代码中隐藏层有4个神经元,激活函数为tansig
(双曲正切函数),用于引入非线性。 - 输出层:输出层只有一个神经元,用于单输出预测。激活函数采用线性函数
purelin
,适合回归任务。
代码讲解
1. 数据加载和归一化
res = readmatrix('回归数据.xlsx'); % 导入数据
X = res(:,1:end-1); % 输入特征
Y = res(:,end); % 输出目标
x = mapminmax(X', 0, 1); % 归一化输入特征
[y, psout] = mapminmax(Y', 0, 1); % 归一化输出目标
- 数据导入:从
回归数据.xlsx
文件中读取数据,X
是输入特征,Y
是目标变量。 - 归一化:将输入和输出数据映射到[0, 1]区间,避免不同特征量级差异对模型带来的影响,并加速训练过程。
mapminmax
函数可以实现归一化,psout
保存归一化参数,用于后续反归一化处理。
2. 划分训练集和测试集
num = size(res,1); % 样本总数
state = randperm(num); % 打乱样本顺序
ratio = 0.8; % 训练集占比
train_num = floor(num * ratio);
x_train = x(:, state(1:train_num));
y_train = y(state(1:train_num));
x_test = x(:, state(train_num+1:end));
y_test = y(state(train_num+1:end));
- 随机打乱样本:通过
randperm
打乱样本顺序,防止数据顺序性对训练带来的偏差。 - 划分数据集:设定80%为训练集,20%为测试集,以确保模型既能学习数据又能测试泛化能力。
3. 创建并配置神经网络
hiddens = 4; % 隐藏层神经元数量
tf = {'tansig', 'purelin'}; % 隐藏层激活函数和输出层激活函数
net = newff(x_train, y_train, hiddens, tf);
- 网络结构:创建一个前馈神经网络
net
,隐藏层包含4个神经元,激活函数使用tansig
;输出层为线性激活函数purelin
,符合回归任务需求。
net.trainParam.epochs = 1000; % 最大训练迭代次数
net.trainParam.goal = 1e-6; % 误差目标
net.trainParam.lr = 0.01; % 学习率
- 设置训练参数:
epochs
:设置最大迭代次数为1000。goal
:设定误差目标为1e-6
,达到该误差则停止训练。lr
:学习率,控制每次权重更新的步长。
4. 训练神经网络
net = train(net, x_train, y_train); % 使用训练集数据训练网络
- 网络训练:使用
train
函数进行训练,通过反向传播算法调整权重,使得预测结果与实际值尽可能接近。
5. 仿真测试与预测
re1 = sim(net, x_train); % 训练集仿真预测
re2 = sim(net, x_test); % 测试集仿真预测
- 仿真预测:使用训练好的神经网络对训练集和测试集数据进行仿真,得到预测值。
6. 数据反归一化
pre1 = mapminmax('reverse', re1, psout); % 反归一化训练集预测结果
pre2 = mapminmax('reverse', re2, psout); % 反归一化测试集预测结果
- 反归一化:将归一化后的预测结果恢复到原始数据的尺度,使得预测值与实际值可直接比较。
7. 计算模型性能指标
% 均方根误差
error1 = sqrt(sum((pre1 - Y_train).^2) ./ train_num);
error2 = sqrt(sum((pre2 - Y_test).^2) ./ test_num);
% R2 指数
R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
R2 = 1 - norm(Y_test - pre2)^2 / norm(Y_test - mean(Y_test))^2;
% 平均绝对误差(MAE)
mae1 = mean(abs(Y_train - pre1));
mae2 = mean(abs(Y_test - pre2));
- 均方根误差(RMSE):衡量预测值与实际值之间的差异,越小越好。
- R²:表示模型的拟合优度,越接近1,表示模型拟合效果越好。
- 平均绝对误差(MAE):反映预测值与实际值的平均绝对差异,越小表示模型性能越好。
8. 结果展示与可视化
- 训练集与测试集的预测对比图:展示预测值与实际值的对比,直观了解模型效果。
- 误差图:展示预测值和实际值之间的百分比误差。
- 拟合图:展示训练集和测试集的回归拟合情况,通过
plotregression
函数直观展示拟合效果。
figure
plot(1: train_num, Y_train, 'r-^', 1: train_num, pre1, 'b-+', 'LineWidth', 1)
legend('真实值','预测值')
xlabel('样本点')
ylabel('预测值')
title('训练集预测结果对比')
figure
plot(1: test_num, Y_test, 'r-^', 1: test_num, pre2, 'b-+', 'LineWidth', 1)
legend('真实值','预测值')
xlabel('样本点')
ylabel('预测值')
title('测试集预测结果对比')
总结
此基于BP神经网络的回归预测模型流程如下:
- 数据预处理:归一化数据,确保不同量纲的特征值不影响训练。
- 构建网络:创建一个多层前馈神经网络,设置隐藏层和输出层的激活函数。
- 模型训练:使用训练集数据优化网络权重,通过迭代训练最小化预测误差。
- 预测与反归一化:对训练集和测试集进行预测,将结果反归一化到原始尺度。
- 性能评估与可视化:通过RMSE、R²、MAE等指标评价模型效果,并通过图形可视化展示模型预测结果。
该模型适用于多输入单输出的回归任务,能够捕捉输入特征与输出目标之间的非线性关系,实现较好的预测效果。
Matlab代码手把手教运行
为了帮助更多的萌新更快上手数学建模建等竞赛,这里直接手把手教会如何直接使用本文中的BP神经网络代码:
close all;clear;clc;
rng(2222)
%% 导入数据
res = readmatrix('回归数据.xlsx');
%% 数据归一化 索引
X = res(:,1:end-1);
Y = res(:,end);
x = mapminmax(X', 0, 1);
%保留归一化后相关参数
[y, psout] = mapminmax(Y', 0, 1);
%% 划分训练集和测试集
num = size(res,1);
state = randperm(num);
ratio = 0.8;
train_num = floor(num*ratio);
x_train = x(:,state(1: train_num));
y_train = y(state(1: train_num));
x_test = x(:,state(train_num+1: end));
y_test = y(state(train_num+1: end));
hiddens = 4; %隐藏层个数
tf = {'tansig', 'purelin'};
net = newff(x_train, y_train, hiddens,tf);
%% 设置参数
net.trainParam.epochs = 1000;
net.trainParam.goal = 1e-6;
net.trainParam.lr = 0.01;
net= train(net, x_train, y_train);
%% 仿真测试
re1 = sim(net, x_train);
re2 = sim(net, x_test );
Y_train = Y(state(1: train_num))';
Y_test = Y(state(train_num+1:end))';
pre1 = mapminmax('reverse', re1, psout);
pre2 = mapminmax('reverse', re2, psout);
error1 = sqrt(sum((pre1 - Y_train).^2) ./ trainnum);
error2 = sqrt(sum((pre2 - Y_test).^2) ./ testnum);
% R2
R1 = 1 - norm(Y_train - pre1)^2 / norm(Y_train - mean(Y_train))^2;
R2 = 1 - norm(Y_test - pre2)^2 / norm(Y_test - mean(Y_test ))^2;
% MAE
mae1 = mean(abs(Y_train - pre1 ));
mae2 = sum(abs(pre2 - Y_test )) ./ testnum ;
disp('训练集预测精度指标如下:')
disp(['训练集数据的R2为:', num2str(R1)])
disp(['训练集数据的MAE为:', num2str(mae1)])
disp(['训练集数据的RMSE为:', num2str(error1)])
disp('测试集预测精度指标如下:')
disp(['测试集数据的R2为:', num2str(R2)])
disp(['测试集数据的MAE为:', num2str(mae2)])
disp(['测试集数据的RMSE为:', num2str(error2)])
figure
plot(1: trainnum, Y_train, 'r-^', 1: trainnum, pre1, 'b-+', 'LineWidth', 1)
legend('真实值','预测值')
xlabel('样本点')
ylabel('预测值')
title('训练集预测结果对比')
figure
plot(1: testnum, Y_test, 'r-^', 1: testnum, pre2, 'b-+', 'LineWidth', 1)
legend('真实值','预测值')
xlabel('样本点')
ylabel('预测值')
title('测试集预测结果对比')
figure
plot((pre1 - Y_train )./Y_train, 'b-o', 'LineWidth', 1)
legend('百分比误差')
xlabel('样本点')
ylabel('误差')
title('训练集百分比误差曲线')
figure
plot((pre2 - Y_test )./Y_test, 'b-o', 'LineWidth', 1)
legend('百分比误差')
xlabel('样本点')
ylabel('误差')
title('测试集百分比误差曲线')
figure;
plotregression(Y_train, pre1, '训练集', ...
Y_test, pre2, '测试集');
set(gcf,'Toolbar','figure');
回归数据.xlsx:
x1 | x2 | x3 | x4 | x5 | y |
---|---|---|---|---|---|
3.036226 | 5613.881 | 217.475 | 68.43483 | 16.82093 | 48.47907612 |
4.391658 | 8450.278 | 231.6231 | 60.47683 | 10.7205 | 64.12185185 |
5.248597 | 8634.475 | 232.9854 | 68.74011 | 11.54856 | 67.67148734 |
5.121236 | 7253.694 | 244.4692 | 65.36061 | 14.36191 | 59.32753057 |
4.649021 | 8647.125 | 268.3052 | 63.80132 | 12.04857 | 67.98570391 |
4.267209 | 5445.033 | 257.7701 | 61.68997 | 7.055625 | 46.47506598 |
4.804512 | 5848.875 | 234.0968 | 67.14467 | 7.656134 | 47.18442579 |
3.825803 | 6583.543 | 270.7575 | 61.44453 | 16.65654 | 54.0487296 |
4.787534 | 9546.304 | 225.8279 | 67.89351 | 11.43665 | 69.90372309 |
5.580797 | 5481.803 | 287.9043 | 62.20432 | 11.26927 | 47.32012957 |
3.658919 | 9482.116 | 278.8093 | 61.20217 | 12.37418 | 71.68429695 |
3.829985 | 9128.034 | 225.2187 | 64.81423 | 16.70461 | 68.18735427 |
5.295785 | 6804.695 | 282.6947 | 67.13434 | 13.61871 | 58.0309376 |
5.554308 | 5340.983 | 277.2833 | 69.39466 | 7.804352 | 48.77931811 |
3.159579 | 8717.524 | 209.9133 | 66.73862 | 16.308 | 67.56410903 |
前几列为特征,最后一列为因变量,直接替换即可无需更改代码!
标签:num,训练,模型,train,BP,Matlab,归一化,test,net From: https://blog.csdn.net/2401_82466443/article/details/143589224