本站原创文章,转载请说明来自《老饼讲解-BP神经网络》www.bbbdata.com
变量过多时,不仅会令BP神经网络易过于过拟合,同时也增加了模型的训练难度
而通过逐步回归选择变量可以有效地减少最终建模变量的个数,从而提高模型的精度与泛化能力
本文讲解如何使用逐步回归的方式来筛选BP神经网络的入模变量,以及示具体的代码实现
本节展示在BP神经网络中添加噪声变量所带来的危害
变量"过多"对BP神经网络的影响
什么是变量过多
变量的信息越精准有效,那么越有利于建模,
但往往建模中会出现变量过多,建模中变量过多理解为两种场情:
👉1. 变量中包含了没有用的变量,例如噪声变量
👉2. 变量之间存在严重的信息冗余
变量过多对BP神经网络的危害
BP神经网络是一个极易过拟合的模型,在BP神经网络建模时,变量过多则会:
一、增强模型的复杂度:
由入输入变量更多,往往需要设置更多的隐节点,将增大模型的复杂度
二、增加了模型的训练难度:
由于模型的解空间更大,求解难度增大,往往会降低模型的训练精度
三、引起模型过拟合:
由于输入变量过多,会使模型更容易过拟合,在同样的训练误差下,模型的测试误差往往会更高
特别是噪声变量,每个噪声变量可能会降低训练数据的误差,但这些贡献只是一种错觉,在测试数据中是无效的
噪声变量对BP神经网络建模效果
下面以matlab自带的acetylene为例,展示噪声变量对BP神经网络的影响
acetylene化学反应数据示例如下:
我们先用acetylene数据的三个变量进行建模,再添加两噪声变量进行建模,然后比对结果
具体实验代码和效果如下:
load acetylene.mat % 加载matlab自带的"化学反应数据"
setdemorandstream(666); % 老饼为了每次运行的结果一致设定随机种子,实际中可以去掉
% -------------没有噪声变量时的建模效果----------------
disp('没有噪声变量时的建模效果')
x = [x1,x2,x3]'; % x1:反应器温度, x2:H2与正庚烷的比率, x3:接触时间
[y,PS] = mapminmax(y',-1,1); % y:正庚烷制乙炔的转化率。这里对y进行归一化是为了方便看误差
net = newff(x,y,5,{'tansig','purelin'},'trainlm'); % 构建BP神经网络
[net,tr,py] = train(net,x,y); % 训练网络
train_err = mean(abs(py(:,tr.trainInd)-y(:,tr.trainInd))) % 训练数据的误差
test_err = mean(abs(py(:,tr.testInd)-y(:,tr.testInd))) % 测试数据的误差
% -----------添加两个噪声变量时的建模效果--------------
disp('添加噪声变量时的建模效果')
x = [x1,x2,x3,rand(length(x1),2)]'; % 增加了两个随机变量作为噪声
net = newff(x,y,5,{'tansig','purelin'},'trainlm'); % 构建BP神经网络
[net,tr,py] = train(net,x,y); % 训练网络
train_err = mean(abs(py(:,tr.trainInd)-y(:,tr.trainInd))) % 训练数据的误差
test_err = mean(abs(py(:,tr.testInd)-y(:,tr.testInd))) % 测试数据的误差
运行结果如下:
没有噪声变量时预测误差为0.09,有噪声变量时0.45
可以看到,噪声变量会大大影响BP神经网络模型的效果
本节简单讲解什么逐步回归建模,以及向前选择逐步回归的流程
什么是逐步回归
逐步回归建模是一种常用的建模方式,它可以有效地减少入模变量个数,加强模型的泛化能力
逐步回归分为"向前选择"与"向后删除"两种方式
向前选择:向前选择就是逐个添加变量进行建模,直到新添加变量不再对模型有所贡献时,则停止添加变量
向后删除:向后删除则是先将所有变量进行建模,然后逐个变量删除,直到满足删除变量会对模型性能有所影响
逐步回归的具体流程(向前选择)
向前选择逐步回归采用逐个变量入模的方式进行建模,具体流程如下:
1. 历遍所有变量,将单个变量与目标建模,把模型结果最好的变量作为第一轮选择变
2. 在第一轮选择变量的基础上,添加第二个变量,
历遍剩余变量,添加哪个变量能令模型结果最好,就将其作为第二轮选择变量
3. 在第二轮的基础上,添加第三个变量......
......
直到变量不再对拟合结果带来明显贡献时,就不再添加变量
向后删除逐步回归是类似的,只是采用逐个减少变量的方式进行建模
本节展示如何使用逐步回归来减少BP神经网络建模的变量个数
BP神经网络-逐步回归建模实例与代码
通过逐步回归来减少BP神经网络建模变量个数,往往能降低模型的训练误差、提高模型的泛化能力
下面仍然以acetylene化学数据作为示例,并添加两个噪声变量,以展示BP神经网络逐步回归建模的效果
BP神经网络-逐步回归具体实现代码如下:
% 本代码用于展示如何使用逐步回归来选择BP神经网络的建模变量
% 本代码来自《老饼讲解-BP神经网络》www.bbbdata.com
% ----------------加载数据---------------------------------
setdemorandstream(999); % 老饼为了每次运行的结果一致设定随机种子,实际中可以去掉
load acetylene.mat % 加载matlab自带的"化学反应数据"
x = [x1,x2,x3,rand(length(x1),2)]'; % x1:反应器温度,x2:H2与正庚烷的比率,x3:接触时间,并增加了两个随机变量作为噪声
[y,PS] = mapminmax(y',-1,1); % y:正庚烷制乙炔的转化率。这里对y进行归一化是为了方便看误差
% ------------使用逐步回归选择建模变量---------------------
var_num = size(x,1); % 变量个数
select_var = []; % 已选择的变量
res_var = 1: var_num; % 未使用的变量
try_num = 10 ; % 尝试的次数
err_record = [mean(abs(mean(y)-y))];
for i = 1:var_num % 逐个变量进行选择
err_list =[]; % 初始化本次各个变量的误差
for cur_var = res_var % 计算添加各个变量后模型的误差
var = [select_var,cur_var]; % 本次用于建模的变量(已选择的变量+本次的变量)
err = 0; % 初始化模型的误差
cur_x = x(var,:); % 本次用于建模的x
for k = 1: try_num % 尝试try_num次,取误差均值作为本变量的模型误差
net = newff(cur_x,y,5,{'tansig','purelin'},'trainlm'); % 构建BP神经网络
net.divideParam.trainRatio = 0.85; % 用于训练的数据比例
net.divideParam.valRatio = 0.15 ; % 用于验证过拟合的数据比例
net.divideParam.testRatio = 0; % 用于测试的数据的比例(不需要测试数据,所以设为0)
[net,tr,py] = train(net,cur_x,y); % 训练网络
err = err + mean(abs(py(:)-y(:)))/try_num; % 更新模型的训练误差
end
err_list = [err_list,err]; % 记录该变量对应的模型误差
end
% 判断本次应该选择哪个变量
[err,idx] = min(err_list); % 找出差误最小的变量
if((err_record(end)-err)<0.01) % 如果加入变量后,误差下降并不明显,则停止添加变量
break
end
err_record=[err_record,err];
select_var = [select_var,res_var(idx)]; % 将本次选出的变量添加到已选变量池中
res_var(idx)=[]; % 从剩余变量池中移除将本次选出的变量
end
select_var % 打印最后选出用于建模的变量
% ---------------使用选出的变量进行建模--------------------
% 这里老饼为了结果的可复现性,设置了随机种子,实际中应该使用选择好的变量多训练几次,选择较好的结果
setdemorandstream(999);
select_x = x(select_var,:); % 用于建模的x
net = newff(select_x,y,5,{'tansig','purelin'},'trainlm'); % 构建BP神经网络
[net,tr,py] = train(net,select_x,y); % 训练网络
% 计算模型预测指标
train_err = mean(abs(py(:,tr.trainInd)-y(:,tr.trainInd))) % 训练数据的误差
test_err = mean(abs(py(:,tr.testInd)-y(:,tr.testInd))) % 测试数据的误差
代码运行结果如下:
在逐步回归中依次选出的变量为x1,x2,x3,可见逐步回归成功地排除了噪声变量x4,x5
最终,使用x1,x2,x3进行建模的结果为:训练误差0.0730,测试误差0.0901
好了,以上就是使用逐步回归来选择BP神经网络入模变量的方法与代码了~
End