机器学习之MATLAB代码--LSTM-SVRNN(五)

时间:2022-12-05 19:04:09

机器学习之MATLAB代码--LSTM-SVRNN(五)

代码

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文件
机器学习之MATLAB代码--LSTM-SVRNN(五)
2、两个mat文件,要的评论。都是一行n维的数组
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)

结果

第一个组合程序运行结果:
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)
lstmnn.m文件运行结果:
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)
机器学习之MATLAB代码--LSTM-SVRNN(五)