代码
1、cdmnn.m文件
%% 组合模型
%%
%% 数据导入
clc;clear;warning off;
data= xlsread('nndata.xlsx', 'sheet1', 'A2:G350');
load LSTMoutput
load SVMoutput
%%
nwhole=length(data);
%计算数据长度
train_ratio=0.90;
ntrain=round(nwhole*train_ratio);
ntest =nwhole-ntrain;
R_train = output_train;
LSTM_train = LSTMoutput_train';
SVM_train = SVMoutput_train;
R_test = output_test;
LSTM_test = LSTMoutput_test';
SVM_test = SVMoutput_test;
%% CDM
% 产生初始解
W0=[0.5;0.5];
LPA=[];
LPB=[];
% 权重等式约束
Aeq=[1 1];
Beq=1;
LB=zeros(2,1);
UB=[1;1];
NONLCON=[];
options = optimset;
[W_train,E_train] = fmincon(@(W)ObjectFunction(W,R_train,LSTM_train,SVM_train),W0,LPA,LPB,Aeq,Beq,LB,UB,NONLCON,options);
[W_test,E_test] = fmincon(@(W)ObjectFunction(W,R_test,LSTM_test,SVM_test),W0,LPA,LPB,Aeq,Beq,LB,UB,NONLCON,options);
fprintf('W_LSTM_test=%f,W_SVM_test=%f',W_test(1),W_test(2))
C_test =W_test(1)*LSTM_test +W_test(2)*SVM_test;
fprintf('\n\n');
%-------------------------------------------------------------------------------------
%%
%% 数据输出
%-------------------------------------------------------------------------------------
disp("——————组合模型预测结果——————————")
%误差计算
LSTM_error_test = LSTM_test -R_test;
LSTM_pererror_test = LSTM_error_test./R_test;
SVM_error_test = SVM_test -R_test;
SVM_pererror_test = SVM_error_test./R_test;
C_error_test = C_test -R_test;
C_pererror_test = C_error_test./R_test;
disp("组合模型预测值 真实值 组合模型误差 组合模型相对误差 ")
disp([C_test R_test C_error_test C_pererror_test])
%-------------------------------------------------------------------------------------
% 指标分析
LSTM_error = LSTM_error_test';
SVM_error = SVM_error_test';
C_error = C_error_test';
LSTM_MAE = sum(abs(LSTM_error))/(ntest);
SVM_MAE = sum(abs( SVM_error))/(ntest);
C_MAE = sum(abs( C_error))/(ntest);
LSTM_pererror = LSTM_pererror_test';
SVM_pererror = SVM_pererror_test';
C_pererror = C_pererror_test';
LSTM_MAPE=sum(abs(LSTM_pererror))/(ntest);
SVM_MAPE=sum(abs( SVM_pererror))/(ntest);
C_MAPE=sum(abs( C_pererror))/(ntest);
LSTM_MSE = mse(LSTM_error);
SVM_MSE = mse(SVM_error);
C_MSE = mse(C_error);
LSTM_RMSE = sqrt(mean((LSTM_error).^2));
SVM_RMSE = sqrt(mean(( SVM_error).^2));
C_RMSE = sqrt(mean(( C_error ).^2));
disp('预测绝对平均误差MAE');
disp('LSTM SVM 组合模型');
disp([LSTM_MAE SVM_MAE C_MAE]);
disp('预测平均绝对误差百分比MAPE');
disp('LSTM SVM 组合模型');
disp([LSTM_MAPE SVM_MAPE C_MAPE]);
disp('预测均方误差MSE')
disp('LSTM SVM 组合模型');
disp([LSTM_MSE SVM_MSE C_MSE]);
disp('预测均方根误差RMSE')
disp('LSTM SVM 组合模型');
disp([LSTM_RMSE SVM_RMSE C_RMSE]);
%-------------------------------------------------------------------------------------
%% 数据可视化分析
%%
%测试数据 模型对比
%-------------------------------------------------------------------------------------
figure();
plot(LSTM_test,':.','Color',[128 0 255]./255,'linewidth',0.8,'Markersize',3) %测试数据分析
hold on
plot(SVM_test, ':*','Color',[64 255 64]./255,'linewidth',0.8,'Markersize',3) %测试数据分析
hold on
plot(C_test,':+','Color',[255 64 64]./255,'linewidth',0.8,'Markersize',3) %测试数据分析
hold on
plot(R_test','k--') %实际数据分析
legend('LSTM预测测试数据','SVM预测测试数据','组合预测测试数据','实际分析数据','Location','NorthWest','FontName','宋体');
string2 = {'网络模型结果及真实值'};
title(string2,'fontsize',12,'FontName','宋体')
xlabel('时间','fontsize',12,'FontName','宋体');
ylabel('数值','fontsize',12,'FontName','宋体');
%-------------------------------------------------------------------------------------
figure()
%误差
plot(LSTM_error_test,':.','Color',[128 0 255]./255,'linewidth',0.8,'Markersize',3)
hold on
plot(SVM_error_test, ':*','Color',[64 255 64]./255,'linewidth',0.8,'Markersize',3)
hold on
plot(C_error_test,':+','Color',[255 64 64]./255,'linewidth',0.8,'Markersize',3)
legend('LSTM测试误差','SVM测试误差','组合测试误差','Location','NorthWest','FontName','宋体');
title('网络预误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
%-------------------------------------------------------------------------------------
figure()
plot(LSTM_pererror_test,':.','Color',[128 0 255]./255,'linewidth',0.8,'Markersize',3)
hold on
plot(SVM_pererror_test, ':*','Color',[64 255 64]./255,'linewidth',0.8,'Markersize',3)
hold on
plot(C_pererror_test,':+','Color',[255 64 64]./255,'linewidth',0.8,'Markersize',3)
legend('LSTM测试相对误差','SVM测试相对误差','组合测试相对误差','Location','NorthWest','FontName','宋体');
title('网络预测相对误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
xlabel('样本','fontsize',12,'FontName','宋体')
%-------------------------------------------------------------------------------------
2、funlstm.m文件
function [LSTMoutput_train,output_train,LSTMoutput_test,output_test,nwhole] = funlstm(data,train_ratio)
input =data(:,1:6)';
output=data(:,7)';
nwhole= length(data);
ntrain=round(nwhole*train_ratio);
ntest =nwhole-ntrain;
% 准备输入和输出训练数据
input_train =input(:,1:ntrain);
output_train=output(:,1:ntrain);
% 准备测试数据
input_test =input (:,ntrain+1:ntrain+ntest);
output_test=output(:,ntrain+1:ntrain+ntest);
%% 归一化(全部特征 均归一化)
[inputn_train,inputps]=mapminmax(input_train);
[outputn_train,outputps]=mapminmax(output_train);
inputn_test=mapminmax('apply',input_test,inputps);
%% LSTM 层设置,参数设置
inputSize = size(inputn_train,1); %数据输入x的特征维度
outputSize = size(outputn_train,1); %数据输出y的维度
numhidden_units1=10*inputSize;
numhidden_units2=120;
numhidden_units3=20*outputSize;
%% lstm
layers = [ ...
sequenceInputLayer(inputSize) %输入层设置
lstmLayer(numhidden_units1,'name','hidden1') %学习层设置(cell层)
dropoutLayer(0.2,'name','dropout_1')
lstmLayer(numhidden_units2,'Outputmode','sequence','name','hidden2')
dropoutLayer(0.3,'name','dropout_2')
lstmLayer(numhidden_units3,'name','hidden3')
dropoutLayer(0.2,'name','dropout_3')
fullyConnectedLayer(outputSize) % 全连接层设置(影响输出维度)
regressionLayer('name','out')];
%% trainoption(lstm)
opts = trainingOptions('adam', ...
'MaxEpochs',400, ...
'GradientThreshold',1,...
'ExecutionEnvironment','cpu',...
'InitialLearnRate',0.005, ...
'LearnRateSchedule','piecewise', ...
'LearnRateDropPeriod',200, ...
'LearnRateDropFactor',0.8, ...
'Verbose',0, ...
'Plots','training-progress'...
);
%% LSTM网络训练
%%
tic
LSTMnet = trainNetwork(inputn_train,outputn_train,layers,opts);
toc;
[LSTMnet,LSTMoutputr_train]= predictAndUpdateState(LSTMnet,inputn_train);
LSTMoutput_train = mapminmax('reverse',LSTMoutputr_train,outputps);
%% LSTM测试数据
%%
%网络测试输出
[~,LSTMoutputr_test] = predictAndUpdateState(LSTMnet,inputn_test);
%网络输出反归一化
LSTMoutput_test= mapminmax('reverse',LSTMoutputr_test,outputps);
end
3、lstmnn.m文件
%%
clc;clear;
warning off;
%导入数据
data= xlsread('nndata.xlsx', 'sheet1', 'A2:G350');
train_ratio=0.90;
[LSTMoutput_train,output_train,LSTMoutput_test,output_test,nwhole] = funlstm(data,train_ratio);
LSTMoutput_train = double(LSTMoutput_train);
output_train = double(output_train);
LSTMoutput_test = double(LSTMoutput_test);
output_test = double(output_test);
ntrain = round(nwhole*train_ratio);
ntest = nwhole-ntrain;
%数据保存
save('LSTMoutput.mat','LSTMoutput_train','output_train','LSTMoutput_test','output_test','-double')
%-------------------------------------------------------------------------------------
error_test=LSTMoutput_test'-output_test';
pererror_test=error_test./output_test';
%% LSTM数据可视化分析
%%
%-------------------------------------------------------------------------------------
%测试数据
figure()
plot(LSTMoutput_test,'r:.') %测试数据分析
hold on
plot(output_test,'k--') %实际数据分析
legend('预测测试数据','实际分析数据','Location','NorthWest','FontName','宋体');
title('LSTM网络模型结果及真实值','fontsize',12,'FontName','宋体')
xlabel('时间','fontsize',12,'FontName','宋体');
ylabel('数值','fontsize',12,'FontName','宋体');
h = gca;
h.FontName = 'Meiryo UI';
h.FontSize = 10;
%-------------------------------------------------------------------------------------
figure()
stem(error_test,'fill','Color',[128 100 255]./255,'linewidth' ,0.8,'Markersize',3)
legend('LSTM网络训练误差','LSTM网络测试误差','Location','NorthEast','FontName','宋体')
title('LSTM网络预测误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
xlabel('样本','fontsize',12,'FontName','宋体')
h = gca;
h.FontName = 'Meiryo UI';
h.FontSize = 10;
%-------------------------------------------------------------------------------------
figure()
stairs(pererror_test,'-.','Color',[255 50 0]./255,'linewidth',0.7)
legend('LSTM网络测试相对误差','Location','NorthEast','FontName','宋体')
title('LSTM网络预测相对误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
xlabel('样本','fontsize',12,'FontName','宋体')
h = gca;
h.FontName = 'Meiryo UI';
h.FontSize = 10;
%-------------------------------------------------------------------------------------
4、ObjectFunction.m文件
function E= ObjectFunction(W,R,LSTM,SVM)
E=sum((R-(W(1)*LSTM+W(2)*SVM)).^2);
end
% %,R,SGM,SVM
% [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = fmincon(FUN,X0,A,B,Aeq,Beq,LB,UB,NONLCON) % 统一形式
% [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = fmincon(F,X0,A,B,Aeq,Beq,LB,UB,NONLCON) % 线性目标函数,包含非线性约束
% [X,FVAL,EXITFLAG,OUTPUT,LAMBDA] = fmincon(@(X)MYOBJ(X),X0,A,B,Aeq,Beq,LB,UB,@(X)MYCON(X)) % 自己定义目标函数和非线性约束函数
% % 目标函数
% function F = MYOBJ(X)
% F = ......
% % 非线性约束函数
% function [G,Heq] = MYCON(X)
% G = ..... % 非线性不等式约束条件
% Heq = ..... % 非线性等式约束条件
%%
% 输入变量
% FUN 为目标函数,可以自己定义,输入变量X,输出目标值
% X0 为初始解
% A 为不等式约束系数矩阵(注意默认不等式方向为小于等于,若为大于等于,需要将其取相反数)
% B 为不等式右端常数向量(注意默认不等式方向为小于等于,若为大于等于,需要将其取相反数)
% Aeq 为等式约束系数矩阵
% Beq 为等式右端常数向量
% LB 为决策变量下界向量
% UB为决策变量上界向量
% NONLCON 为非线性约束,可以自己定义,其中包括非线性不等式约束,非线性等式约束两种约束。输入变量X,输出不等式计算值,等式计算值
% 在调用时,输入参数不存在时,可以将其输入用 [] 空矩阵表示。
%
% 输出变量
% X 为最优解
% FVAL 为最优目标值
% EXITFLAG 为运行结束标志,当等于1时,表示程序收敛于解 X;当等于0时,表示程序运行次数到达最大;当小于0时,说明情况较多
% OUTPUT 为程序迭代次数
% LAMBDA 为解X相关的Largrange乘子和影子价格
5、svmnn.m文件
clc;clear;
warning off;
%% SVM
%%
data= xlsread('nndata.xlsx', 'sheet1', 'A2:G350');
%计算数据长度
input =data(:,1:6);
output=data(:,7);
nwhole=length(data);
train_ratio=0.90;
ntrain=round(nwhole*train_ratio);
ntest =nwhole-ntrain;
% 准备输入和输出训练数据
input_train =input(1:ntrain,:);
output_train=output(1:ntrain,:);
% 准备测试数据
input_test =input(ntrain+1:end,:);
output_test=output(ntrain+1:end,:);
%% 预测
[SVMoutput_train,trainoption] = SVMRP(input_train,output_train,input_train,output_train);
[SVMoutput_test,testoption] = SVMRP(input_train,output_train,input_test, output_test);
%数据保存
save('SVMoutput.mat','SVMoutput_train','output_train','SVMoutput_test','output_test','-double')
error_test=SVMoutput_test-output_test;
pererror_test=error_test./output_test;
%-------------------------------------------------------------------------------------
%% 数据可视化分析
%%
%-------------------------------------------------------------------------------------
%测试数据
figure();
plot(SVMoutput_test,'r:.') %测试数据分析
hold on
plot(output_test','k--') %实际数据分析
legend('预测测试数据','实际分析数据','Location','NorthWest','FontName','宋体');
title('SVM网络模型结果及真实值','fontsize',12,'FontName','宋体')
xlabel('时间','fontsize',12,'FontName','宋体');
ylabel('数值','fontsize',12,'FontName','宋体');
%-------------------------------------------------------------------------------------
figure()
stem(error_test,'fill','Color',[128 100 255]./255,'linewidth' ,0.8,'Markersize',3)
legend('SVM网络测试误差','Location','NorthEast','FontName','宋体')
title('SVM网络预测误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
xlabel('样本','fontsize',12,'FontName','宋体')
%-------------------------------------------------------------------------------------
figure()
stairs(pererror_test,'r-.','linewidth',0.8)
legend('SVM网络测试相对误差','Location','NorthEast','FontName','宋体')
title('SVM网络预测相对误差','fontsize',12,'FontName','宋体')
ylabel('误差','fontsize',12,'FontName','宋体')
xlabel('样本','fontsize',12,'FontName','宋体')
%-------------------------------------------------------------------------------------
6、SVMRP.m文件
function [predict_test,testoption] = SVMRP(p_train,t_train,p_test,t_test)
%UNTITLED 此处显示有关此函数的摘要
% 此处显示详细说明
%% 数据归一化
%%
% 训练集
[pn_train,inputps] = mapminmax(p_train');
pn_train = pn_train';
[tn_train,outputps] = mapminmax(t_train');
tn_train = tn_train';
% 测试集
pn_test = mapminmax('apply',p_test',inputps);
pn_test = pn_test';
tn_test = mapminmax('apply',t_test',outputps);
tn_test = tn_test';
%% SVM模型创建/训练
%%
% 1. 寻找最佳c参数/g参数
[c,g] = meshgrid(-10:0.5:10,-10:0.5:10);
[m,n] = size(c);
cg = zeros(m,n);
eps = 10^(-4);
v = 5;
bestc = 0;
bestg = 0;
error = Inf;
for i = 1:m
for j = 1:n
cmd = ['-v ',num2str(v),' -t 2',' -c ',num2str(2^c(i,j)),' -g ',num2str(2^g(i,j) ),' -s 3 -p 0.1'];
cg(i,j) = svmtrain(tn_train,pn_train,cmd);
if cg(i,j) < error
error = cg(i,j);
bestc = 2^c(i,j);
bestg = 2^g(i,j);
end
if abs(cg(i,j) - error) <= eps && bestc > 2^c(i,j)
error = cg(i,j);
bestc = 2^c(i,j);
bestg = 2^g(i,j);
end
end
end
%%
% 2. 创建/训练SVM
cmd = [' -t 2',' -c ',num2str(bestc),' -g ',num2str(bestg),' -s 3 -p 0.01'];
model = svmtrain(tn_train,pn_train,cmd);
%% SVM仿真预测
[Predict_test,testoption] = svmpredict(tn_test,pn_test,model);
% 反归一化
predict_test = mapminmax('reverse',Predict_test,outputps);
end
数据
nndata.slsx文件
2、两个mat文件,要的评论。都是一行n维的数组
结果
第一个组合程序运行结果:
lstmnn.m文件运行结果: