For automatic forecasting of large numbers of time series, the ATSM packages provides access to the most robust models available today based on diagnosing the characters of each time series. However, for experienced forecasters, sometimes you might have the desire to create your own model based on industry related insights. This paper describes how to build custom model using Time Series Model (TSM) package in PROC TSMODEL.
The reader of this paper is assumed to have already known about PROC TSMODEL (if not, please read PROC TSMODEL 101 first).
The time series model (TSM) package surfaces a set of time series modeling objects that provide a flexible way to model and forecast univariate time series. It contains:
The object classes in the TSM package are described briefly here:
Object 
Description 
TSM 
Time series model class used to forecast univariate time series models 
ARIMASPEC 
ARIMA model specification class used to define custom ARIMA models 
ESMSPEC 
Exponential Smoothing Model (ESM) model specification class used to define custom ESM models 
IDMSPEC 
Intermittent Demand Model (IDM) model specification class used to define custom IDM models. 
UCMSPEC 
Unobserved Component Model (UCM) model specification class used to define custom UCM models 
EXMSPEC 
External Model (EXM) model specification class used to define external forecast computations 
TSMPEST 
Collector class used to store time series model parameter estimates from a TSM instance. 
TSMSPEC 
Collector class used to store time series model XML. 
TSMFOR 
Collector for TSM model forecasts 
TSMINEST 
Repeater class used to replay time series model parameter estimates from a CAS table. 
TSMINSPEC 
Repeater class used to replay time series model XML specifications from a CAS table. 
For a detailed description, synopsis and methods of each object in the TSM package, please click here.
For experienced SAS users, the TSMODEL procedure and TSM package are designed to provide functionality and capabilities that are similar to what is available with the following SAS 9.4 procedures:
Now, we will talk about how to build custom models using TSM model, so that it can be reused in the subsequent TSMODEL calls. The steps are simple:
Let’s walk through the steps by several examples.
In this example, we take the airline passenger data from sashelp library, fit a Winters model with multiplicative seasonality, and forecast 12 periods out.
cas mycas; libname mylib cas sessref = mycas;
data mylib.aircas; set sashelp.air; run; proc tsmodel data=mylib.aircas outscalar=mylib.scalars outarray=mylib.predict lead=12;
*use TSM package; register tsm;
id date interval=month; var air; outarray predict; outscalar nfor mase; submit;
*declare TSM objects; declare object spec(esmspec); declare object esm(tsm);
*specify ESM model parameters; rc = spec.Open(); rc = spec.SetTransform('log','median'); rc = spec.SetOption('method', 'winters'); rc = spec.SetOption('criterion', 'mase'); rc = spec.Close();
*set time series, run ESM model; rc = esm.Initialize(spec); rc = esm.SetY(air); rc = esm.Run();
*collect the statistics from the model; nfor = esm.nfor(); mase = esm.criterion('fit');
*collect the forecasts into object called predict; rc = esm.GetForecast('predict',predict);
endsubmit; run;
*print the output tables; proc print data=mylib.scalars; run; proc print data=mylib.predict; run;

The process flow in the program statement block of PROC TSMODEL is as follows:
First, we declared the required TSM objects, an instance for ESMSPEC class object and an instance for TSM class object.
Next, we specify the parameters for this ESM model. It includes instructing the code to take logarithm transformation of the prediction variable, use median as prediction semantics for the inverse transform, use multiplicative Winters model, and set MASE as the model estimation criterion.
Then we set up the dependent variable, air, and run the ESM model.
Finally, we collect some statistics from the model into the scalar output table, and the forecast results into the array output table.
Let us take a look at the output tables. The scalar output table “mylib.scalars” displays the size of the predict series “nfor” and the mean absolute standard error “mase”.
The array output table “mylib.predict” includes the basic columns of outarray table, and a column we named as “predict” in the code for forecast results. Below is a screen capture of the first couple of rows for this table.
Based on the same data, now let’s build a different model, a moving average model Y_{t}=0.25y_{t1}+0.25y_{t2}+0.25y_{t3}+0.25y_{t4}.
proc tsmodel data=mylib.aircas outarray=mylib.predict lead=12; register tsm; id date interval=month; var air; outarray predict; submit; *moving average forecasts; declare object mavgSpec(ARIMASPEC); declare object mavgTsm(TSM);
*specify moving average model parameters; rc = mavgSpec.open(); *setup spec for moving average of window 4; beta = 1/4; array AROrder[4]/nosymbols; array ARCoeff[4]/nosymbols; AROrder[1] = 1; AROrder[2] = 2; AROrder[3] = 3; AROrder[4] = 4; ARCoeff[1] = beta; ARCoeff[2] = beta; ARCoeff[3] = beta; ARCoeff[4] = beta;
rc = mavgSpec.addARPoly(AROrder, 4, 0, ARCoeff); *no estimate, no intercept; rc = mavgSpec.setOption('noint', 1, 'noest', 1, 'nostable', 1); rc = mavgSpec.close();
*setup the TSM object; rc = mavgTsm.initialize(mavgSpec); rc = mavgTsm.setY(air); rc = mavgTsm.setOption('lead', 12); rc = mavgTsm.run();
*collect the forecast; rc = mavgTsm.getForecast('predict', predict);
endsubmit; run; 
To build moving average model, we use the ARIMASPEC object. The code above specifies the 4 AR terms and their corresponding orders, coefficients for the 4 terms, add these orders and coefficients into the ARIMASPEC instance mavgSpec, and set the options to make sure no intercept is included and no estimation is needed. After running the specified model, we collect the forecast results.
Below is an example illustrating how to specify an ARIMAX model, which considers both the dependent variable and independent variables in the model. This example also shows how to collect the results through TSM object method.
cas mycas; libname mylib cas sessref = mycas;
*prepare the input data; data mylib.pricedata; set sashelp.pricedata; run; *extend 12 periods out; proc tsmodel data = mylib.pricedata out = mylib.pricedata_aug lead = 12; by regionname productline productname; id date interval=month; var sale /acc = sum setmiss=miss; var price/acc = avg setmiss=PREV; run; *fill out the independent variable values for the future 12 periods; proc tsmodel data = mylib.pricedata_aug out = mylib.pricedata_ext; by regionname productline productname; id date interval=month; var sale /acc = sum setmiss=miss; var price/acc = avg setmiss=PREV; run;
*build the ARIMAX model; proc tsmodel data = mylib.pricedata_ext outobj = ( outFor = mylib.outFor outEst = mylib.outEst ); by regionname productline productname; id date interval=month; var sale /acc = sum; var price/acc = avg;
*use TSM package; require tsm; submit; *declare TSM objects; declare object arima(ARIMASPEC); declare object tsm(TSM); declare object outest(TSMPEST); declare object outfor(TSMFOR);
array diff[1]/nosymbols (1); array ar[3]/nosymbols (1 2 3); array ma[1]/nosymbols (1);
*specify arima model parameters arima (3,1,0)(0,0,1)s with x(1); rc = arima.open();
*usage: rc = ARIMASpec.SetDiff(DiffArray[,NDiff]); rc = arima.setDiff(diff);
*usage: rc = ARIMASpec.AddARPoly(OrderArray[,NOrder,Seasonal,CoeffArray]); rc = arima.addARPoly(ar,3,0);
*usage: rc = ARIMASpec.AddMAPoly(OrderArray[,NOrder,Seasonal,CoeffArray]); rc = arima.addMAPoly(ma,1,1);
*usage: rc = ARIMASpec.AddTF(XName[,Delay,DiffArray,NDiff]); rc = arima.addTF('price', 0, diff);
rc = arima.setOption('method', 'ml'); rc = arima.close();
*set options: y and x variables, lead, model; rc = tsm.initialize(arima); rc = tsm.setY(sale); rc = tsm.addX(price); rc = tsm.setOption('lead',12); rc = tsm.run();
*collect the forecasts into object called outfor; rc = outfor.collect(tsm); *collect the estimates into object called outest; rc = outest.collect(tsm); endsubmit; run; 
In a summary, this code requires the TSM package, utilizes ARIMASPEC to define the model, uses TSM object to fit the model, and then generates two output tables using the collect method of the TSM object instance.
The process flow is as follows:
First, we start by specifying the seasonal ARIMA model (3,1,0)(0,0,1)s with differencing X using ARIMASPEC object instance. We do this by specifying the differencing on dependent variable, autoregressive (AR) polynomial factor, and moving average (MA) polynomial factor using the corresponding methods. Then we add a differencing function to the model for the specified independent variable “price”. We also set the option to make the sure model will be estimated based on maximal likelihood function.
Next, we initialize the TSM object instance based on the ARIMA model we specified. We define the time series for analysis by adding the dependent variable (sale) and independent variable (price) into the TSM object. After specifying the forecast lead to be 12, we instruct the TSM object instance to estimate and forecast the time series sale based on the ARIMA model.
Finally, we collect the relevant forecast results and model estimation results for review and downstream processes. The output of the collected objects are saved in CAS tables. They can be reviewed for forecasting validation and improvement. The OUTEST table, can also be used as inputs to the repeater objects in userdefined programs to customize the time series analysis workflows.
Let us take a look at the output tables. Below is a description of the available output tables, with a screen capture of the first couple of rows for each table.
The forecast table (mylib.outFor) includes the forecast results with the STD and UPPER & LOWER values for each time series.
The estimate table (mylib.outEst) includes the estimates of the model parameters for each time series.
This document has briefly introduced TSM package in PROC TSMODEL, demonstrated how to create custom models and generate forecast using TSM package. For more information, please see the documentation for the TSM packages, and PROC TSMODEL in the SAS Viya forecasting documentation.
SAS is headed back to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team.
Interested in speaking? Content from our attendees is one of the reasons that makes SAS Innovate such a special event!
Data Literacy is for all, even absolute beginners. Jump on board with this free elearning and boost your career prospects.