Matlab神经网络滚动预测——预测未来

一、前言

Matlab神经网络滚动预测——预测未来
目前有很多Matlab神经网络时序预测的代码,绝大部分都是验证性质的,即对现有的数据进行验证,时序预测最重要的是预测未来,本文整理了一套简单的神经网络时序预测预测未来的代码,且本代码是完整的可用的,没有残缺,复制文中的代码到Matlab即可运行出结果。
代码共分为7部分,分别为:初始化、数据读取、数据归一化、权值阈值、反归一化、预测、作图。

二、代码部分

1、初始化

%% 1.初始化
clear
close all
clc

2、数据读取

需要修改的地方有:
(1)A1:A16代表数据范围,类似于有16年的数据;
(2)k+4,4代表时序预测的延时算子,1:12中的12=16-4;
(3)其他参数适当修改。

%% 2.数据读取
data0=xlsread('数据.xlsx','Sheet1','A1:A16');
b=data0(:,1)';
data=cell2mat(arrayfun(@(k) b(k:k+4),1:12,'un',0)');%转换矩阵,建一个形式如Hilbert矩阵的形式
[rowLen, colLen] = size(data); % rowLen代表矩阵的行数,collen代表列数
trainNum = rowLen;       % 训练样本数量
hiddenNum = 11;          % 隐含层
input = colLen - 1;      % 输入层
output = 1;              % 输出层
p = data(:, 1:input)';   % 输入数据矩阵
t = data(:, colLen)';    % 目标数据矩阵

3、数据归一化

参数适当修改

%% 3.数据归一化
[SamIn, PSp] = mapminmax(p, -1, 1);   
[tn, PSt] = mapminmax(t, -1, 1);
SamOut = tn;         % 输出样本
MaxEpochs = 30000;   % 最大训练次数
lr = 0.05;           % 学习率
E0 = 1e-3;           % 目标误差
rng('default');

4、权值阈值

%% 4.权值阈值
W1 = rand(hiddenNum, input);      % 初始化输入层与隐含层之间的权值
B1 = rand(hiddenNum, 1);          % 初始化输入层与隐含层之间的阈值
W2 = rand(output, hiddenNum);     % 初始化输出层与隐含层之间的权值              
B2 = rand(output, 1);             % 初始化输出层与隐含层之间的阈值
ErrHistory = zeros(MaxEpochs, 1);     
for i = 1 : MaxEpochs   
    HiddenOut = logsig(W1*SamIn + repmat(B1, 1, trainNum));   % 隐含层网络输出
    NetworkOut = W2*HiddenOut + repmat(B2, 1, trainNum);      % 输出层网络输出
    Error = SamOut - NetworkOut;       % 实际输出与网络输出之差
    SSE = sumsqr(Error);               % 能量函数(误差平方和)
    ErrHistory(i) = SSE;               % 记录每次学习的误差
    if SSE < E0                        % 如果达到误差阈值就退出
        break;
    end
    % 权值(阈值)依据能量函数负梯度下降原理所作的每一步动态调整量
    Delta2 = Error;
    Delta1 = W2' * Delta2 .* HiddenOut .* (1 - HiddenOut);    
    dW2 = Delta2 * HiddenOut';
    dB2 = Delta2 * ones(trainNum, 1); 
    dW1 = Delta1 * SamIn';
    dB1 = Delta1 * ones(trainNum, 1);
    % 对输出层与隐含层之间的权值和阈值进行修正
    W2 = W2 + lr*dW2;
    B2 = B2 + lr*dB2;
    % 对输入层与隐含层之间的权值和阈值进行修正
    W1 = W1 + lr*dW1;
    B1 = B1 + lr*dB1;
end
HiddenOut = logsig(W1*SamIn + repmat(B1, 1, trainNum));   % 隐含层输出最终结果
NetworkOut = W2*HiddenOut + repmat(B2, 1, trainNum);      % 输出层输出最终结果

5、反归一化

tFit = mapminmax('reverse', NetworkOut, PSt); %反归一化

6、预测

需要修改的地方:
(1)1 : 12中的12是总样本数减去延时算子数;
(2)preP = zeros(1, 4)和for i = 1 : 4中的4代表要预测的未来4个,例如预测未来4年的数据。

x = 1 : 12;   % 样本数减去预测数
ForcastSamNum = 1;
preP = zeros(1, 4);
pNew = data(end, 2:end)';    % 最后一行是输入,竖着排
for i = 1 : 4
    pnew = pNew;  
    pnewn = mapminmax('apply', pnew, PSp);      % 归一化
    HiddenOut = logsig(W1*pnewn + repmat(B1, 1, ForcastSamNum));  % 隐含层输出预测结果
    anewn = W2*HiddenOut + repmat(B2, 1, ForcastSamNum);          % 输出层输出预测结果
    anew = mapminmax('reverse', anewn, PSt);     % 反归一化
    preP(i) = anew;                              % 保存预测值
    pNew = [pNew(2:end); anew];                  % 新预测的值作为下一次的输入
end

7、作图

需注意:plot(13:16)是要预测的未来4年,通常来说16个样本,预测未来4个,应该plot(17:20),怎么会是(13:16)呢?这里将延时算子的4组数据删减掉了,因此16-4=12,应该从13起plot4年的数据,也就是(13:16)。

figure
plot(x, t, 'k:o','linewidth',1.5);
hold on
plot(x, tFit, 'r-^','linewidth',1.5);
hold on
plot(13:16, preP, 'b--h','linewidth',1.5);
legend('真实值', '拟合值', '预测值');
xlabel('序列'),ylabel('指标值');
set(gca,'fontsize',12)

figure
plot(x, tFit - t, '--o','linewidth',1.5);
hold on
plot(x, abs(tFit - t) ./ t, '--*','linewidth',1.5)
legend('绝对误差', '相对误差');
xlabel('序列'),ylabel('误差');

disp('预测值:');
disp(preP);

三、结果展示

在这里插入图片描述
在这里插入图片描述

四、结语

这是一组非常简单的滚动预测代码,也有缺陷,偶尔会收敛不了,对于震动幅度大的数据可能无法分析出结果。

猜你喜欢

转载自blog.csdn.net/baoliang12345/article/details/127855650