How can predict multi step ahead using Narnet
Show older comments
I want to predict the future prices, I have used only the daily historical prices as input. I can predict only one step ahead using this code:
clear all;
clear all;
load('prices.mat');
set_size = 1413;
targetSeries =prices(1:set_size);
targetSeries = targetSeries';
targetSeries_train = targetSeries(1:set_size * (4/5) );
targetSeries_test = targetSeries(set_size * (4/5): end);
targetSeries_train = num2cell(targetSeries_train);
targetSeries_test = num2cell(targetSeries_test);
feedbackDelays = 1:4;
hiddenLayerSize = 10;
net = narnet(feedbackDelays, hiddenLayerSize);
net.inputs{1}.processFcns = {'removeconstantrows','mapminmax'};
[inputs, inputStates, layerStates,targets] = preparets(net,{},{}, targetSeries_train);
[inputs_test,inputStates_test,layerStates_test,targets_test] = preparets(net,{},{},targetSeries_test);
net.trainFcn = 'trainrp'; % Levenberg-Marquardt
net.performFcn = 'mse'; % Mean squared error
net.plotFcns = {'plotperform','plottrainstate','plotresponse', ...
'ploterrcorr', 'plotinerrcorr'};
[net,tr] = train(net,inputs,targets,inputStates,layerStates);
outputs = net(inputs_test,inputStates_test,layerStates_test);
errors = gsubtract(targets_test,outputs);
performance = perform(net,targets_test,outputs)
view(net)
% netc = closeloop(net);
% [xc,xic,aic,tc] = preparets(netc,{},{},targetSeries_test);
% yc = netc(xc,xic,aic);
% perfc = perform(net,tc,yc)
% nets = removedelay(net);
% [xs,xis,ais,ts] = preparets(nets,{},{},targetSeries_test);
% ys = nets(xs,xis,ais);
% stepAheadPerformance = perform(net,ts,ys)
how I can predict multistep ahead, for example the prediction of 10 days in advance.
Thanks in advance.
2 Comments
John D'Errico
on 14 Jul 2014
Argh! Learn how to use the code formatting tool. I'll fix it this once. See that your code is unreadable as it WAS, but after one click of the mouse it is now readable.
coqui
on 14 Nov 2014
Edited: Walter Roberson
on 6 Aug 2015
Accepted Answer
More Answers (2)
Greg Heath
on 17 Jul 2014
%0. a. I do not have MATLAB on this computer, so some of my code comments may need correcting.
% b. I will not complain if you decide to change your mind and accept my answer
% c. Did you mean to begin with close all instead of two clears?
clear all;
clear all;
load('prices.mat');
set_size = 1413;
targetSeries = prices(1:set_size);
targetSeries = targetSeries';
targetSeries_train = targetSeries(1:set_size * (4/5) );
targetSeries_test = targetSeries(set_size * (4/5): end);}
%1. setsize*4/5 is not an integer
% 2. Why are you trying to avoid the default validation set used to avoid overtraining an overfit net (i.e., more unknown weights than training equations)?
% 3. WARNING: You will have to override the default net.divideFcn = 'dividerand' and associated net.divide... trn/val/tst ratios 0.7/0.15/0.15. Use net.divideFcn = 'dividetrain' with the default ratios 100/0/0. I don't think any other option allows absense of a val set.
%4. HOWEVER, my recommendation is to use net.divideFcn = 'divideblock' and accept the default ratios 0.7/0.15/0.15 . Otherwise is more trouble than it's worth. You will automatically get all three results at once.
targetSeries_train = num2cell(targetSeries_train);
targetSeries_test = num2cell(targetSeries_test);
% 5. OK, but check out function tonndata
feedbackDelays = 1:4;
%6. Use the significant delays indicated by the autocorrelation function. For examples search greg narnet nncorr
hiddenLayerSize = 10;
% 7. Default value of 10 may not work well. However, it is good for preliminary investigation because Numweights = ( 4+1)*10+(10+1)*1= 61 << Numtrainequations = 1130
net = narnet(feedbackDelays, hiddenLayerSize);
net.inputs{1}.processFcns = {'removeconstantrows','mapminmax'};
% 8. Unnecessary this is a default
[inputs, inputStates, layerStates,targets] = preparets(net,{},{}, targetSeries_train);
[inputs_test,inputStates_test,layerStates_test,targets_test] = preparets(net,{},{}, targetSeries_test);
net.trainFcn = 'trainrp'; % Levenberg-Marquardt
%9. INCORRECT. 'trainlm' is L-M;
net.performFcn = 'mse'; % Mean squared error
net.plotFcns = {'plotperform','plottrainstate','plotresponse', 'ploterrcorr', 'plotinerrcorr'};
% 10. Last 3 statements are defaults. Can omit to simplify code
[net,tr] = train(net,inputs,targets,inputStates,layerStates);
% 11. INCORRECT . You did not change the defaults net.divideFcn = 'dividerand' and net.divideRatio = 0.7/0.15/0.15
outputs = net(inputs_test,inputStates_test,layerStates_test);
errors = gsubtract(targets_test,outputs);
performance = perform(net,targets_test,outputs)
view(net)
netc = closeloop(net);
[xc,xic,aic,tc] = preparets(netc,{},{},targetSeries_test);
%%yc = netc(xc,xic,aic);
perfc = perform(net,tc,yc)
%12. Often closing the loop so degrades performance that you have to train netc
%%nets = removedelay(net);
% %[xs,xis,ais,ts] = preparets(nets,{},{},targetSeries_test);
% %ys = nets(xs,xis,ais);
% %stepAheadPerformance = perform(net,ts,ys)
how I can predict multistep ahead, for example the prediction of 10 days in advance.
% 13. I DON'T UNDERSTAND the use of removedelay. The significant delays of the autocorrelation function indicate how far you can predict ahead with probabilistic certainty. So 1<= FD <= dmax and the values may be nonconsecutive. I think removedelay removes the lower values of FD with, I assume, a decrease in performance. When my computer is available I will investigate.
%Hope this helps.
%Thank you for formally accepting my answer
Greg
8 Comments
coqui
on 17 Jul 2014
coqui
on 17 Jul 2014
Greg Heath
on 19 Jul 2014
I don't understand your problem because you have not posted your attempt.
coqui
on 19 Jul 2014
Greg Heath
on 20 Jul 2014
tr=tr
will show the trn/val/tst indices. Therefore you can use the command
hold on
to overlay the separate trn/val/tst results ('b','g','r') over the original data ('k--').
coqui
on 24 Jul 2014
Edited: Walter Roberson
on 6 Aug 2015
Greg Heath
on 24 Jul 2014
Search the NEWSGROUP and ANSWERS using combinations of
greg
timedelaynet, narnet or narxnet
nncorr
Hub, Hmin:dH:Hmax
Hope this helps.
Greg
MAT-Magic
on 28 Mar 2020
Thanks Greg, I am reading the posts in your google group :)
coqui
on 25 Jul 2014
0 votes
26 Comments
Greg Heath
on 26 Jul 2014
Edited: Greg Heath
on 26 Jul 2014
2 is good for fitnet and patternnet
1 is good for narnet(FD)
For timedelaynet replace MXFD with MXID: timedelaynet(ID)
For narxnet use both
coqui
on 30 Jul 2014
Greg Heath
on 31 Jul 2014
Looks OK
coqui
on 2 Aug 2014
coqui
on 30 May 2015
Greg Heath
on 31 May 2015
Edited: Greg Heath
on 31 May 2015
That should give you all of the lags associated with absolute values of correlations above the 95% confidence level for noise.
Try to use the smallest subset of the smallest lags that will yield your training goal. For example, if the significant lags are 1 3 4 7 ..., I would first try [ 1 3 ]. If unsuccessful, add 4 and 7 etc.
P.S. I just posted a NEWSGROUP example of finding the significant autocorrelation lags for the simplenar_dataset.
coqui
on 31 May 2015
coqui
on 31 May 2015
Greg Heath
on 31 May 2015
This is incorrect. The length of the output of NNCORR is 2*N-1 whereas the length of the fft method is only N.
BOTTOM LINE :
Use the same method to calculate sigthresh95 and siglags.
coqui
on 1 Jun 2015
Greg Heath
on 1 Jun 2015
No.
Your previous formula for autocorrn was correct. whereas your previous formula for M was incorrect
coqui
on 3 Jun 2015
coqui
on 3 Jun 2015
Greg Heath
on 4 Jun 2015
I don't believe there is just one significant lag. Please post your data in *.m or *.txt.
coqui
on 5 Jun 2015
Greg Heath
on 6 Jun 2015
Edited: Greg Heath
on 6 Jun 2015
There are 1752 significant lags. The first 20 are given below
[ O N ] = size(t) % [ 1 3263 ]
zt = zscore(t',1)';
L = floor(0.95*(2*N-1));
for i=1:100
zn = zscore(randn(1,N),1);
autocorrn = nncorr(zn,zn,N-1,'biased');
sortabsautocorrn = sort(abs(autocorrn));
thresh95(i) = sortabsautocorrn(L);
end
sigthresh = mean(thresh95) % 0.025642
stdsigthresh = std(thresh95) % 0.00063742
autocorrt = nncorr(zt,zt,N-1,'unbiased');
siglags = -1+find(abs(autocorrt(N+1:2*N-1))>sigthresh);
Nsig = size(siglags) % 1752
FD = siglags(2:21)
% 1 2 3 4 5 6 7 8 9 11
% 12 13 14 15 16 20 21 25 26 31
Ideally, choose the smallest subset of the smaller values that will yield an acceptable result.
Hope this helps.
Greg
coqui
on 6 Jun 2015
coqui
on 7 Jun 2015
Greg Heath
on 7 Jun 2015
Edited: Greg Heath
on 7 Jun 2015
With a data set of your size, determine parameters with the training set and validate with the validation set. Verify consistency using multiple designs with different initial weights. If you wish, you can use the multiplicity to estimate standard deviations on error estimates.
For stability I try to minimize the number of delays, size of the delays and number of hidden nodes.
When all is said and done, obtain an UNBIASED estimate using the test set which, in no way, is used to determine the design.
Hope this helps.
Greg
coqui
on 7 Jun 2015
Greg Heath
on 23 Jun 2015
The basic reason for the trn/val/tst division is to make sure that the final design and it's estimates are as unbiased w.r.t. the details of the individual design (training+val) data as possible.
Ideally, you would like Ntrn to be large enough to make reliable estimates of the correlation functions. The most practical approach is to use crossvalidation or bootstrapping estimation to estimate reliability.
Hope this helps.
Greg
coqui
on 3 Jul 2015
Greg Heath
on 3 Jul 2015
My advice:
1. Use the training subset to choose the significant lags. Keep validation predictions as unbiased as possible.
2. There is a formal way: Use the method of partial correlations that chooses lags one-by-one taking into account previously selected correlations. However, this method will yield gaps. I have never tried this.
3. You could choose a subset of the significant correlations by ordering the magnitude. However, that will usually also leave gaps; Similarly, ordering significant correlation lags also tends to have gaps (e.g., 9,11 and 17,19).
4. I prefer to have
a. No gaps
b. As small a continuous subset as possible containing, possibly, non-significant correlations.
c. Trial and error might find me first trying 1:4 and, if unsuccessful, maybe trying 1:8 (even if the correlation at one or more of the intermediate lags is not significant).
Your choice.
Hope this helps.
Greg
coqui
on 5 Jul 2015
Greg Heath
on 7 Aug 2015
Start with a subset containing the first few. If that doesn't work, add more.
If you plot the autocorreltion function, the two threshold lines, and color the points outside of the lines red, you will get a much better idea of what is going on. Similarly for crosscorrelations.
EanX
on 1 Oct 2015
To obtain 10 steps-ahead forecast, I have to use an empty cell array as input to closed loop net or a cell array of NaN? I suppose that both methods will work so a tried this code:
clearvars; clc; close all;
% test with a simple dataset
Y=simplenar_dataset;
net = narnet(1:4,3);
net.trainParam.showWindow = false;
T = Y(1:80);%tonndata(Y,false,false);
% use only first 80 samples to train and the remaining 20
% to test predictions
Tpred=Y(81:end);
[Xs,Xi,Ai,Ts] = preparets(net,{},{},T);
% is necessary to add Xi and Ai to closeloop to have xic1 and aci1
[net, xic1, aic1] = closeloop(train(net,Xs,Ts,Xi,Ai),Xi,Ai);
% NaN method, require to set first 4 (equal to delay) values
Ypred = nan(14,1);
Ypred = tonndata(Ypred,false,false);
Ypred(1:4) = T(end-3:end);
% empty cells method
Xc1=cell(1,10);
[xc,xic,aic,tc] = preparets(net,{},{},Ypred);
% prediction resulting from the two methods does not agree
% empty cell does not work but perhaps I'm missing something?
% empty cells method
Ypred1 = fromnndata(net(Xc1,xic1,aic1),true,false,false);
Ypred = fromnndata(net(xc,xic,aic),true,false,false); % NaN method
% plot results
plot([Ypred Ypred1 cell2mat(Tpred(1:10))']);
legend('Pred-NaN','Pred-EmptyCells','Target');
But I obtain different results. What am I missing? Thanks.
Categories
Find more on Modeling and Prediction with NARX and Time-Delay Networks in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!