In most cases, generating predictions of the future with timeseries or machine learning models requires providing lead or future values for the input variables that these models contain. This two-post sequence focuses on functionality in the TSMODEL procedure that enables the creation and implementation of input variable future values.
The previous post in this series (see https://communities.sas.com/t5/SAS-Communities-Library/Proc-TSMODEL-Notes-Creating-Input-Variable-Le...) described functionality for the creation and implementation of lead values for deterministic inputs in the forecasting system. This process is manual in the sense that the user directly controls the input lead values for variable arrays created in TSMODEL.
The purpose of part 2 will be to focus on more automated approaches and the creation of stochastic input variable lead values. For stochastic, time-varying input variables, like a customer’s credit score or the yield on US treasuries, future values are not known with certainty.
We’ll start with an augmented version of the table introduced in the last post. In the table below, a stochastic input, X1, has been added. The deterministic input variable, TIME, has known future values, and these are already in the table. Recall that the forecast horizon will be defined to start in the interval after the last non-missing value for the dependent variable, here Y, for each array or BY group (here ACCOUNT). Our job is to generate useful future values for the stochastic input, X1.
Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.
There are a few different options for providing future values for stochastic inputs. We could just extend each X1 array into the future using a constant based on the most recent known value. This is a conservative approach, and it could adversely impact the precision of the forecast for Y. If there is systematic variation in X1, a better option for providing future values may be to build a model to forecast it. We’ll show two ways of doing this in SAS Visual Forecasting next.
Demo 1, Using an Exponential Smoothing model to forecast stochastic input variables.
We’ll use the Automatic Timeseries Modeling (ATSM) package in the TSMODEL procedure to automatically generate lead values for the X1 input variable.
Note, this discussion assumes that you’re already familiar with the ATSM package and most of the syntax shown. If a tutorial on using the ATSM package to generate forecasts will be helpful, the following webinar provides one; https://www.youtube.com/watch?v=r84p_EzPOpo&t=30s.
proc tsmodel data=casuser.blogleads
outobj = (
blogfor=casuser.forecasts
blogindep=casuser.independentvars
blogmodelinfo = casuser.modelinfo
);
id date interval=month;
by account;
var Y time X1;
*use the ATSM package;
require atsm;
submit;
*declare ATSM objects;
declare object dataFrame(tsdf);
declare object myDiagnose(diagnose);
declare object myDiagSpec(diagspec);
declare object forecast(foreng);
declare object blogFor(outfor);
declare object blogindep(outindep);
declare object blogmodelinfo(outest);
*setup dependent and independent variables;
rc = dataFrame.initialize();
rc = dataFrame.addY(y);
rc = dataFrame.addX(time);
* exend X1 uisng an ESM model;
rc = dataFrame.addX(x1, 'extend', 'stochastic');
*setup time series diagnose specifications;
rc = myDiagSpec.open();
rc = myDiagSpec.setArimax('identify', 'reg');
rc = myDiagSpec.close();
*diagnose time series to generate candidate model list;
rc = myDiagnose.initialize(dataFrame);
rc = myDiagnose.setSpec(myDiagSpec);
rc = myDiagnose.run();
*run model selection and forecast;
rc = forecast.initialize(myDiagnose);
rc = forecast.setOption('lead', 6);
rc = forecast.run();
*collect automatic forecasting results;
rc = blogFor.collect(forecast);
rc = blogindep.collect(forecast);
rc = blogmodelinfo.collect(forecast);
endsubmit;
run;
Relevant syntax for extending X1
The lead values for the input variables are automatically used in generating future forecasts for the dependent variable.
Demo 2, Using an ARIMAX model to generate leads for stochastic input variables.
Something that wasn’t discussed in the previous demonstration is that we had more than one dependent variable in the Submit block of TSMODEL. Temporarily, each input variable becomes a dependent variable for the purpose of forecasting its lead values. If we use an ESM to generate lead values, functionality in the ATSM package handles this for us and we don’t have to think about it.
To use a more general model to generate lead values for an input, we need to accommodate this switching between dependent and independent variable roles for each input in the syntax. The syntax below has been modified to use an ARIMAX model to generate lead values for X1, and then use these in the generation of forecasts for Y. The model to generate lead values for X1 uses TIME as a candidate input and will identify ARMA type variation in X1.
Note, ESM models, as shown in demo 1, are usually sufficient for forecasting lead values for inputs. This demo’s approach may be occasionally useful. The main reason it’s included is that it illustrates some not widely known aspects of the TSMODEL procedure functionality as well as its overall flexibility.
We’ll use two data frames in the Submit block of the code shown below to handle X1 first as a dependent variable and then as an independent variable to predict Y.
proc tsmodel data=casuser.blogleads outsum=casuser.aaaa outarray=casuser.blogleadsout (replace=yes)
outobj = (
blogfor=casuser.forecasts
blogmodelinfo = casuser.modelinfo
);
id date interval=month trimid=both;
by account ;
var Y time X1;
outarray X1_lead x1n;
require atsm;
submit;
declare object df1(tsdf);
declare object df2(tsdf);
declare object myDiagnose(diagnose);
declare object myDiagSpec(diagspec);
declare object forecast(foreng);
declare object blogFor(outfor);
declare object blogmodelinfo(outest);
rc = df1.initialize();
rc = df1.addY(X1);
rc = df1.addX(time);
rc = myDiagSpec.open();
rc = myDiagSpec.setArimax('identify', 'reg');
rc = myDiagSpec.close();
rc = myDiagnose.initialize(df1);
rc = myDiagnose.setSpec(myDiagSpec);
rc = myDiagnose.run();
rc = forecast.initialize(mydiagnose);
rc = forecast.setOption('lead', 6);
rc = forecast.run();
rc = forecast.getForecast('Predict', X1_lead);
do i = 1 to dim(x1_lead);
if x1[i] ne . then do;
x1n[i] = x1[i];
end;
else do;
x1n[i] = x1_lead[i];
end;
end;
...
The first data frame in the syntax above, DF1, sets the metadata for creating lead values for X1; addY and addX methods specify that X1 is the dependent and TIME is an X or input variable.
Subsequently,
…
rc = df2.initialize();
rc = df2.addY(Y);
rc = df2.addX(x1n);
rc = df2.addX(time);
rc = myDiagnose.initialize(df2);
rc = myDiagnose.setSpec(myDiagSpec);
rc = myDiagnose.run();
rc = forecast.initialize(mydiagnose);
rc = forecast.setOption('lead', 6);
rc = forecast.run();
*collect automatic forecasting results;
rc = blogFor.collect(forecast);
rc = blogmodelinfo.collect(forecast);
endsubmit;
run;
In the next post, we’ll continue to focus on the TSMODEL procedure and illustrate an approach to speed up processing time in a large-scale forecasting scenario. Stay tuned for more TSMODEL procedure action!
Find more articles from SAS Global Enablement and Learning here.
Visit the Tips & Tricks page for setup guidance, demos, and practical examples that show how Copilot supports your workflows.
The rapid growth of AI technologies is driving an AI skills gap and demand for AI talent. Ready to grow your AI literacy? SAS offers free ways to get started for beginners, business leaders, and analytics professionals of all skill levels. Your future self will thank you.