只做了部分解释,比较粗糙,只是记录一下
所用数据集前12行如下
(其实只用了第2,3行数据(年,月),第5行数据(月温度值),第七行(年/月))
(用第七行是因为想要x轴显示为'年/月'格式的日期)
所用代码如下:
%% matlab编程实现的BP神经网
络时间序列预测模型
% 清空环境变量
clear
close all %关闭所有图形窗口
clc
[StepData,txt]=xlsread('C:\Users\lenovo\Desktop\年月1.xlsx');%读取csv文件
%%第一步 读取数据
input=StepData(:,2:3); %载入输入数据年月
output=StepData(:,5); %载入输出数据月温度
X1=txt(2:1213,7);
xn=datenum(X1);
X2=txt(1214:1487,7);
xnn=datenum(X2);
X=txt(2:1487,7);
xnnn=datenum(X);
%% 第二步 设置训练数据和预测数据
% 注意要将指标变为列向量
input_train = input(1:1212,:)';
output_train =output(1:1212,:)';
input_test = input(1213:1486,:)';
output_test =output(1213:1486,:)';
%节点个数
inputnum=1213; % 输入层节点数量,也就是训练集样本数 1212+1
hiddennum=4; % 隐含层节点数量
outputnum=1; % 输出层节点数量 计算的是月温度1组数据
%% 第三本 训练样本数据归一化
[inputn,inputps]=mapminmax(input_train);%归一化到[-1,1]之间,inputps用来作下一次同样的归一化
[outputn,outputps]=mapminmax(output_train);
%% 第四步 构建BP神经网络
net=newff(inputn,outputn,hiddennum,{'tansig','purelin'},'trainlm');% 建立模型,传递函数使用purelin,采用梯度下降法训练
W1= net. iw{1, 1}; %输入层到中间层的权值
B1 = net.b{1}; %中间各层神经元阈值
W2 = net.lw{2,1}; %中间层到输出层的权值
B2 = net. b{2}; %输出层各神经元阈值
%% 第五步 网络参数配置( 训练次数,学习速率,训练目标最小误差等)
net.trainParam.epochs=1000; % 训练次数,这里设置为1000次
net.trainParam.lr=0.01; % 学习速率,这里设置为0.01
net.trainParam.goal=0.00001; % 训练目标最小误差,这里设置为0.00001
%% 第六步 BP神经网络训练
net=train(net,inputn,outputn);%开始训练,其中inputn,outputn分别为输入输出样本
%% 第七步 测试样本归一化
inputn_test=mapminmax('apply',input_test,inputps); % 对样本数据进行归一化
%% 第八步 BP神经网络预测
an=sim(net,inputn_test); %用训练好的模型进行仿真
%% 第九步 预测结果反归一化与误差计算
test_simu=mapminmax('reverse',an,outputps); %把仿真得到的数据还原为原始的数量级
error=test_simu-output_test; %预测值和真实值的误差
%训练集仿真
an0=sim(net,inputn);
train_simu=mapminmax('reverse',an0,outputps);
%训练集图
figure('units','normalized','position',[0.119 0.2 0.38 0.5])
plot(xn,output_train,'bo-','markersize',1,'markerfacecolor','b')
datetick('x','yyyy-mm')
hold on
plot(train_simu,'rs-','markersize',2,'markerfacecolor','r')
grid on
legend('Actual value','Predicted value')
xlabel('Date')
ylabel('Temperature')
title('Plot of the predicted and actual values of the training set')
%%第十步 真实值与预测值误差比较
figure('units','normalized','position',[0.119 0.2 0.38 0.5])
plot(xnn,output_test,'bo-','markersize',1,'markerfacecolor','b')
datetick('x','yyyy-mm')
hold on
plot(xnn,test_simu,'rs-','markersize',1,'markerfacecolor','r')
grid on
legend('Actual value','Predicted value')
xlabel('Date')
ylabel('Temperature')
title('Plot of the predicted and actual values of the test se')
%描述过去1899至2021年气温
figure('units','normalized','position',[0.119 0.2 0.38 0.5])
plot(xn,output_train,'go-','markersize',1,'markerfacecolor','g')
datetick('x','yyyy-mm')
hold on
plot(xn,train_simu,'bs-','markersize',1,'markerfacecolor','b')
hold on
plot(xnn,output_test,'go-','markersize',1,'markerfacecolor','g')
hold on
plot(xnn,test_simu,'bs-','markersize',1,'markerfacecolor','b')
grid on
legend('Actual value','Predicted value')
xlabel('Date')
ylabel('Temperature')
title('Graph of actual and predicted temperature from 1899 to 2021')
%显示误差
[c,l]=size(output_test);
MAE1=sum(abs(error))/l;
MSE1=sum(error.^2)/l;
RMSE1=MSE1^(1/2);
MAPE1=sum(abs(error./output_test))/l;
R=corrcoef(output_test,test_simu);
R2=R(1,2)^2;
disp(['Calculation of error:'])
disp(['Error results when the number of hidden layer nodes is ',num2str(hiddennum)])
disp(['Mean absolute error(MAE): ',num2str(MAE1)])
disp(['Mean square error(MSE): ',num2str(MSE1)])
disp(['Root mean square error(RMSE): ',num2str(RMSE1)])
disp(['Mean relative error(MAPE): ',num2str(MAPE1)])
disp(['Coefficient of determination(R^2): ',num2str(R2)])
%预测2050年和2100年每月温度
x=zeros(24,2);
for i=1:1:12
x(i,1)=2050;
x(i,2)=i;
x(i+12,1)=2100;
x(i+12,2)=i;
end
predict_y = zeros(24,1); % 初始化predict_y
pre_test=mapminmax('apply',x',inputps);% 对预测数据进行归一化
for i = 1: 24
result = sim(net, pre_test(:,i));
predict_y(i) = result;
end
disp('Monthly temperature projections for 2050 and 2100:')
predict_y=mapminmax('reverse',predict_y,outputps); %把预测结果还原
disp(predict_y)
%预测2050年和2100年年温度
disp('Predicted mean temperature for 2050 and 2100:')
y=zeros(2,1);
for i = 1: 12
y(1)=predict_y(i) +y(1);
y(2)=predict_y(i+12) +y(2);
end
y(1)=y(1)/12;
y(2)=y(2)/12;
disp(y)