%% 基于果蝇优化的BP神经网络预测
clear all
clc
warning off;
%%%
clear
clc
rng('default');
%% 导入数据
%数据导入
%%
clc;clear;
warning off;
%% 导入数据
%%
data = xlsread('data.xlsx');
% 输入数据
input =data(1:end-1,1:end-1);
output=data(2:end,end);
nwhole =size(data,1)-1;
tic
%训练/测试数据
train_ratio=0.8;
ntrain=round(nwhole*train_ratio);
ntest =nwhole-ntrain;
% 随机生成训练集、测试集
k = 1:size(input,1);
% 准备输入和输出训练数据
input_train =input(k(1:ntrain),:)';
output_train=output(k(1:ntrain),:)';
% 准备测试数据
input_test =input(k(ntrain+1:ntrain+ntest),:)';
output_test=output(k(ntrain+1:ntrain+ntest),:)';
M = size(input_train,2);
N = size(input_test,2);
% 训练集
P_train=input_train;
T_train=output_train;
% 测试集
P_test=input_test;
T_test=output_test;
%% 归一化
% 训练集
[Pn_train,inputps] = mapminmax(P_train,-1,1);
Pn_test = mapminmax('apply',P_test,inputps);
% 测试集
[Tn_train,outputps] = mapminmax(T_train,-1,1);
Tn_test = mapminmax('apply',T_test,outputps);
%% 构造网络结构
%创建神经网络
inputnum = 7; %inputnum 输入层节点数
hiddennum = 21; %hiddennum 隐含层节点数
outputnum = 1; %outputnum 隐含层节点数
%% 构造果蝇优化器
popsize = 10;%种群数量
Max_iteration = 20;%最大迭代次数
lb = -2;%权值阈值下边界
ub = 2;%权值阈值上边界
% inputnum * hiddennum + hiddennum*outputnum 为权值的个数
% hiddennum + outputnum 为阈值的个数
dim = inputnum * hiddennum + hiddennum*outputnum + hiddennum + outputnum ;% inputnum * hiddennum + hiddennum*outputnum维度
fobj = @(x)funBP(x,inputnum,hiddennum,outputnum,Pn_train,Tn_train,Pn_test,Tn_test);
[Best_score,Best_pos,FOA_cg_curve,net]=FOA(fobj,popsize,Max_iteration,lb,ub,dim);
figure
plot(FOA_cg_curve)
title('迭代曲线')
xlabel('迭代次数');
ylabel('损失值');
legend('FOA')
grid on;
disp('初始化阈值与权值信息:')
FOABPn_train = sim(net, Pn_train);
FOABPn_test = sim(net, Pn_test);
% 反归一化
FOABP_train = mapminmax('reverse',FOABPn_train,outputps);
FOABP_test = mapminmax('reverse',FOABPn_test,outputps);
%% 数据输出
%% 绘图
figure
plot(FOABP_train,'r-o','linewidth',1)
hold on
plot(T_train,'b-*','linewidth',1)
legend('FOA-BP预测输出','实际数据','Location','NorthWest','FontName','华文宋体');
title('模型训练结果及真实值','fontsize',12,'FontName','华文宋体')
xlabel('训练集样本编号','fontsize',12,'FontName','华文宋体');
ylabel('数值','fontsize',12,'FontName','华文宋体');
xlim([1, M])
grid
figure
plot(FOABP_test,'r-o','linewidth',1)
hold on
plot(T_test,'b-*','linewidth',1)
legend( 'FOA-BP预测输出','实际数据','Location','NorthWest','FontName','华文宋体');
title('模型测试结果及真实值','fontsize',12,'FontName','华文宋体')
xlabel('测试集样本编号','fontsize',12,'FontName','华文宋体');
ylabel('数值','fontsize',12,'FontName','华文宋体');
xlim([1, N])
grid
%% 分割线
disp('**************************')
disp(['下列是输出'])
disp('**************************')
%% 相关指标计算
% R2
R1 = 1 - norm(output_train - FOABP_train)^2 / norm(output_train - mean(output_train))^2;
R2 = 1 - norm(output_test - FOABP_test)^2 / norm(output_test - mean(output_test))^2;
disp(['训练集数据的R2为:', num2str(R1)])
disp(['测试集数据的R2为:', num2str(R2)])
% MAPE
mape1 = sum(abs(FOABP_train - output_train)./output_train) ./ M ;
mape2 = sum(abs(FOABP_test - output_test)./output_test) ./ N ;
disp(['训练集数据的MAPE为:', num2str(mape1)])
disp(['测试集数据的MAPE为:', num2str(mape2)])
% RMSE
rmse1= sqrt(sumsqr(output_train - FOABP_train)/M);
rmse2= sqrt(sumsqr(output_test - FOABP_test)/N);
disp(['训练集数据的RMSE为:', num2str(rmse1)])
disp(['测试集数据的RMSE为:', num2str(rmse2)])
% MSE
mse1= sumsqr(output_train - FOABP_train)/M;
mse2= sumsqr(output_test - FOABP_test)/N;
disp(['训练集数据的MSE为:', num2str(mse1)])
disp(['测试集数据的MSE为:', num2str(mse2)])