# How to use A NARX to predict future using valid input data

28 views (last 30 days)
PK on 3 Jan 2017
Edited: Armin Niaki on 6 Jan 2017
I am using Matlab 2016a on a 64-bit Windows 7 Professional Machine. I have 132 input data as: [61.17;341.5600] [65.4800;328.2080] [64.8800;355.4050] and ........ and 120 output data as: 62352 95856 89124....... I generated a Closed-Loop NARX to predict the output data for input vectors X1(121:128). However, I am only able to simulate 120 outputs for 120 inputs and I cannot predict the future outputs using the valid inputs X1(121:128). I used the following code to simulate the outputs:
u1 = X1(1:90); % X1 is the input data
y1 = Y1(1:90); % Y1 is the output data
[p1,Pi1,Ai1,t1] = preparets(net_closed,u1,{},y1);
yp1 = net_closed(p1,Pi1,Ai1);
TS = size(t1,2);
plot(1:TS,cell2mat(t1),'b',1:TS,cell2mat(yp1),'r')
the resulting graph is : How can I change my code to predict the outputs for inputs 120:128? Thank you in advance.

Greg Heath on 4 Jan 2017
Woefully insufficient information. What was the error on your openloop design?
If you are really serious about getting help, post the full code and results when operating on the documentation example.
Greg
Armin Niaki on 6 Jan 2017
I am working on the same problem as PK is. The objective is to obtain 12-month predictions for the response Y1 (target) based on X1 which currently holds 9variables (7 of which have significant correlations to the response). The response only has 128 timesteps. the last 12 months have been set aside to serve as performance indicators versus the 12 month prediction of the network given these values. Please see attached data to find X(t) and Y(t) (https://docs.google.com/spreadsheets/d/1PU4yiEkoJ9z4635jXAOMpC2_8I0y2ylPcGUmWV-s3u8/edit?usp=sharing).
Here is where we are at now: - Given X1 (9 input variables - 1x116 cell), and Y1 (a times series as target 1x116), as seen in the provided file, the network is trained [Based on my observation, the network provides far better results with the Bayesian learning algorithm 'trainbr']. After a satisfactory model has been trained/re-trained, we attempted to modify the values of both Xc, Xic, but did not mess with Aic and ran the following in the command bar:
ycforecast1=netc(Xc, Xic, Aic)
X = X1;
T = Y1;
trainFcn = 'trainlm';
inputDelays = 1:2;
feedbackDelays = 1:2;
hiddenLayerSize = 10;
net = narxnet(inputDelays,feedbackDelays,hiddenLayerSize,'open',trainFcn);
[x,xi,ai,t] = preparets(net,X,{},T);
net.divideParam.trainRatio = 70/100; net.divideParam.valRatio = 15/100; net.divideParam.testRatio = 15/100; [net,tr] = train(net,x,t,xi,ai); y = net(x,xi,ai); e = gsubtract(t,y); performance = perform(net,t,y) view(net) netc = closeloop(net); netc.name = [net.name ' - Closed Loop']; view(netc) [xc,xic,aic,tc] = preparets(netc,X,{},T); yc = netc(xc,xic,aic); closedLoopPerformance = perform(net,tc,yc) nets = removedelay(net); nets.name = [net.name ' - Predict One Step Ahead']; view(nets) [xs,xis,ais,ts] = preparets(nets,X,{},T); ys = nets(xs,xis,ais); TS = size(ts,2); plot(1:TS,cell2mat(ts),'b',1:TS,cell2mat(ys),'r') stepAheadPerformance = perform(nets,ts,ys)
The value of Xic was set as a 1x2 cell (the 115 and 116th values for the 9 variables in X(t) - and the value of Xc is set as a 1x12 cell that is comprised of the last 12 month X(t)'s that we set aside initially.
After going through what I mentioned, ycforecast1 gave 12 values back which we interpreted as the forecasts of the trained network given the last 12 X(t)'s we fed it - However, the values seemed so off that I didn't even think about calculating the MAPE of the model for its predictions. Any suggestions?

Rajat Kathuria on 5 Jan 2017
Edited: Rajat Kathuria on 5 Jan 2017
Though, it's still not clear what you intend to achieve from your script, I assume you want to predict time-series (T) WITHOUT an exogenous variable (X). In that case, you need to use narnet and not narXnet. The following script (from your original script) will give you one-step forecast in variable 'y'
u1 = num2cell(1:90);
feedbackDelays = 1:2;
hiddenLayerSize = 10;
net = narnet(feedbackDelays,hiddenLayerSize); %Note, I used narnet (not narXnet)
[X, Xi, Ai, T] = preparets(net,{},{},u1);
[net,tr] = train(net, X, T, Xi, Ai);
%for prediction
nets = removedelay(net);
X2 = num2cell(120:128); %length of input series is 9
[xs,xis,ais,ts] = preparets(nets,{},{},X2);
y = nets(xs,xis,ais)
%Note, since there are two predictor variables ('feedbackDelays'), %there will be 8 corresponding predictions for an input series of length 9. %e.g. first inputs, 120 and 121 yields first output, ~122. last inputs 127 and 128 yields final %output ~129. Results may slightly vary depending on your training but, network seems to have %learnt this trivial linear trend well.

#### 1 Comment

PK on 5 Jan 2017
Rajat, Thanks for the answer. I want to use X2 as an input to predict the output with the NARX that I trained with X1 and Y1(netc or nets). I used X1 and Y1 to generate a NARX, it is "netc" (Closed loop after training) in my code. Now, I need to use this NARX to predict Y from X2 (continuation of X1 in 10 more timesteps). I think narnet is for a case that you don't have any input after the last timestep. But, I have X2 as input for the future predictions. My question is: How do I use netc to predict Y from X2? Thanks.

PK on 4 Jan 2017
Greg, Sorry for posting insufficient data. The code for NARX generation is:
X = X1;
T = Y1;
trainFcn = 'trainlm';
inputDelays = 1:2;
feedbackDelays = 1:2;
hiddenLayerSize = 10;
net = narxnet(inputDelays,feedbackDelays,hiddenLayerSize,'open',trainFcn);
[x,xi,ai,t] = preparets(net,X,{},T);
net.divideParam.trainRatio = 70/100;
net.divideParam.valRatio = 15/100;
net.divideParam.testRatio = 15/100;
[net,tr] = train(net,x,t,xi,ai);
y = net(x,xi,ai);
e = gsubtract(t,y);
performance = perform(net,t,y)
view(net)
netc = closeloop(net);
netc.name = [net.name ' - Closed Loop'];
view(netc)
[xc,xic,aic,tc] = preparets(netc,X,{},T);
yc = netc(xc,xic,aic);
closedLoopPerformance = perform(net,tc,yc)
nets = removedelay(net);
nets.name = [net.name ' - Predict One Step Ahead'];
view(nets)
[xs,xis,ais,ts] = preparets(nets,X,{},T);
ys = nets(xs,xis,ais);
TS = size(ts,2);
plot(1:TS,cell2mat(ts),'b',1:TS,cell2mat(ys),'r')