BookmarkSubscribeRSS Feed

AI powered Time-Series Forecasting in Visual Analytics: GenAI Foundation Models in action

Started ‎09-04-2024 by
Modified ‎09-04-2024 by
Views 451

The field of time series forecasting has traditionally been dominated by statistical and machine learning models, but recent advancements in deep learning, particularly the development of foundation models (FMs), are beginning to revolutionize this domain.
Foundation models, also known as large pre-trained models, are deep learning models trained on vast and diverse datasets, enabling them to acquire broad general knowledge and patterns across multiple domains. These models have shown remarkable success in fields like computer vision and natural language processing, where their ability to be fine-tuned for specific tasks with relatively small amounts of data has proven highly effective.
Inspired by these successes, the concept of Time Series Foundation Models (TSFMs) has emerged as a promising approach for time series analysis. TSFMs leverage the foundation model paradigm to create generalized models capable of understanding and forecasting time series data across various applications. Examples of TSFMs include Amazon Science's Chronos models.

 

Chronos is a language modeling framework adapted for time series forecasting. It employs a minimalist approach by tokenizing time series values into a fixed vocabulary (through scaling and quantization of real values) and training existing language model architectures on these tokens without any time-series-specific design or features. Despite its simplicity, Chronos has shown to be effective, having comparable and occasionally superior zero-shot performance on unseen datasets, relative to methods that were trained specifically on them. For more details on Chronos's methodology and performance, refer to the paper linked here.

 

This article explores the application of foundation models for time series forecasting and demonstrates how users can leverage SAS® Visual Analytics (VA) to train and compare these advanced models with traditional forecasting techniques, such as Moving Average, Seasonal Naive, and Exponential Smoothing (ESM).

 

To enable users to train and compare models directly within the VA dashboard, this solution combines Data-Driven Content and SAS® Jobs. Specifically:

  • The SAS® Job will be used to execute SAS® code and pass parameters to it, via HTTP calls to the SAS® Job Execution Web application. The latter allows to create, manage and execute SAS® Jobs, and can be accessed at: http://<your.host.name>/SASJobExecution/.
  • The Data-Driven Content (DDC) object will be used to embed the job into the VA report and transfer information from SAS® Visual Analytics to SAS® Jobs.

The executed SAS® code updates the CAS table used in the dashboard, allowing users to visualize different forecasted values in a single time series plot and select the best model. This solution supports datasets with:

  • 1 date variable
  • 1 BY variable
  • 1 dependent variable

This means your original dataset can include additional variables, but only these three—date, BY, and dependent variable—will be utilized by the SAS® code and VA dashboard. However, the solution can be expanded in future versions to include multiple BY variables or independent variables.

 

This article is divided into two sections:

  1. The first section explains the HTML form and SAS® code behind the job to clarify the logic.
  2. The second section guides you through deploying this project for your use.

 

NoteThe SAS® Job's code accesses the Chronos model by calling an API endpoint where it is deployed. If you want to learn how to achieve this within your SAS® Viya installation, check out the first of a two-part series of articles on incorporating pre-trained forecasting models into SAS® Visual Forecasting.


Project Description

For clarity, this section utilizes a specific dataset, such as the PRICEDATA table from the SASHELP library, though you can easily adapt the steps to any dataset of your choice.

 

Before diving into the code, let's first examine the final outcome, i.e. the VA dashboard:

 

Figure 1 - ModelComparison reportFigure 1 - ModelComparison report

 

The dashboard comprises four different objects:

  1. Drop-down List: Filters the other dashboard objects, allowing focus on a specific subset of data.
  2. Time Series Plot: Displays both historical data (in blue) and forecasted values from various models.
  3. List: Enables users to toggle the visibility of forecasted values for each model.
  4. Data-Driven Content (DDC): Allows users to select which model to train based on the subset of data defined by the drop-down list. If no selection is made, the model is trained on the entire dataset. This implies that different models can be trained for different values of the BY variable.

Behind the scenes, the CAS table is updated with the forecasted values after each model is trained. To ensure the time series plot and list objects reflect these updates, automatic refresh is enabled; otherwise, these objects won't refresh as the data changes with the job execution.

 

Note: Automatic refresh only works when viewing the report, as explained in the documentation.

 

Data Pre-Processing

As mentioned, the forecasted values are plotted alongside historical data in the time series plot. To achieve this without altering the table structure (such as adding a new column for the forecasted values of the selected model), the PRICEDATA table (or your chosen dataset) undergoes pre-processing. This pre-processing is handled by the code in the following two screenshots (from the preprocessing.sas file). The red boxes highlight all the macro variables you can modify to adapt the code to your dataset, which are:

  • originaltab, which stores the name of the original table in the format libname.tablename.
  • castab, which stores the name of the final table in the format libname.tablename.
  • target, which stores the name of the dependent variable to forecast.
  • date, which stores the name of the date variable.
  • byvar, which stores the name of the BY variable.

Figure 2 - SAS pre-processing code: part 1Figure 2 - SAS pre-processing code: part 1Figure 3 - SAS pre-processing code: part 2Figure 3 - SAS pre-processing code: part 2

 

The pre-processing is performed in the PROC CAS procedure. Here’s a step-by-step explanation of what the code does:

  • A dictionary casTbl is created, storing CAS library and CAS table names.
  • A SOURCE block is used to embed an SQL query in a variable named long_table. This query creates a new table (&castab) by selecting and summing the variable &target grouped by &byvar and &date from a temporary table &castab._tmp.
  • The SQL query is executed in the CAS server using the execDirect CAS action.
  • The just created table is reshaped from wide format to long format using the wideToLong action from the dataShaping CAS action set. The final table contains the columns specified in the id parameter and three other columns:
    • _Variable_, whose values are variable names in the input table.
    • _Value_, whose values are values in the input table.
    • _C0_, which stores the character component of the variable names. In this case, it coincides with _Variable_ column, since all the original column names don’t contain numeric values. See here for more information.
  • The _C0_ variable is dropped from the table, while the _Variable_ and _Value_ columns  are renamed to variableName and variableValue respectively, by means of the alterTable CAS action.
  • Finally, the &castab table is promoted to a globally accessible table in the CAS environment, so that it can be used in Visual Analytics. Keeping the variables in the specified order (retain statement) and setting the length of the variableName to 23 characters (length statement) is important not to have problems in the following, when we will append the forecasted values to this table.

As an example, the following image illustrates the PRICEDATA table before and after pre-processing:

 

Figure 4 - PRICEDATA table before and after pre-processingFigure 4 - PRICEDATA table before and after pre-processing

 

With the dataset now prepared, we can begin describing the SAS® Job.

 

SAS® Job Code

The SAS® code is composed of several sections:

  • Initialization. This section sets up the environment and defines necessary macros and options:

    Figure 5 - SAS Job code: initializationFigure 5 - SAS Job code: initialization

    In particular:
    • The sendApplicationMsg macro is defined, which sends a message back to the client in JSON format, indicating the success or failure of the operation. If the process fails (success=false), it closes the CAS session and aborts the job.
    • A CAS connection is established and the &caslib library is assigned.
    • The checkParams macro verifies the presence of all required SAS® global macro variables (model, castab, byvariable, target, date, date_interval, byvar). These variables are automatically generated from the job input parameters included in the HTTP request sent by the HTML form (as explained in the next section). If any variables are missing, the macro triggers an error message and terminates the process.
  • Main Processing. This section handles the core processing based on the value of the byvariable and model parameters.
    • Data Preparation. Depending on whether byvariable is provided, the code either groups by date alone or by both byvar and date. It creates a new CAS table (&castab._aggregate) with the summed variableValue.

      Figure 6 - SAS Job code: data preparationFigure 6 - SAS Job code: data preparation

       

    • Model-Specific Forecasting. The code then applies different forecasting models based on the model parameter. Each block uses the PROC TSMODEL procedure to run a time series model on the data and generate forecasts. As an example, the following screenshots illustrate the code used to retrieve forecasted values from the Chronos model:

      Figure 7 - SAS Job code: model-specific forecasting (Chronos example), part 1Figure 7 - SAS Job code: model-specific forecasting (Chronos example), part 1Figure 8 - SAS Job code: model-specific forecasting (Chronos example), part 2Figure 8 - SAS Job code: model-specific forecasting (Chronos example), part 2Figure 9 - SAS Job code: model-specific forecasting (Chronos example), part 3Figure 9 - SAS Job code: model-specific forecasting (Chronos example), part 3

       

      For a detailed explanation of the code and step-by-step instructions on building a node for the Chronos model in SAS® Visual Forecasting, refer to the second article in the two-part series mentioned in the introduction.
      Note: Despite its name, the Seasonal Naive model simplifies to a standard Naive model in the absence of seasonality, which occurs when the default length of the seasonal cycle associated with the &date_interval is 1 (for instance, when &date_interval=year) or when SEASONALITY=1 is explicitly set in the PROC TSMODEL statement.
  • Post-Processing. After generating the forecasts, the code reshapes and formats the output table by dropping unnecessary columns and converting it from wide to long format. The columns are then renamed and formatted as needed before appending the table’s rows to the final dataset.

    Figure 10 - SAS Job code: post-processingFigure 10 - SAS Job code: post-processing
  • Termination. Finally, the CAS session is terminated, and a final success message is sent back in JSON format using the sendApplicationMsg macro. 

    Figure 11 - SAS Job code: terminationFigure 11 - SAS Job code: termination

 

HTML Form

Let's examine the HTML form, beginning with the head section.

 

Figure 12 - HTML form: head sectionFigure 12 - HTML form: head section

 

The JavaScript code embedded in the HTML (described below) leverages some functions from two modules defined in the GitHub project called sas-visualanalytics-thirdpartyvisualizations. For this reason, they have been uploaded to the Files service and included in the HTML form using the SAS® Job Execution Web Application with a SCRIPT tag (as explained in the documentation). In the final section of the article, the complete procedure to do that will be provided.

 

The body section defines:

  • A heading titled “Select a Model to Train”;
  • Four buttons, each representing a different forecasting model:
    • Moving Average
    • Seasonal Naive
    • Exponential Smoothing Model (ESM)
    • Chronos

Initially, all buttons are disabled and are only enabled once the data is received from the VA dashboard.

  • A div element with ID “JobResults” to display the outcome of the job execution. It will show messages like "Waiting for job to finish...", "Done!", or error messages depending on the job's success or failure.

Figure 13 - HTML form: body sectionFigure 13 - HTML form: body section

 

Next, let's examine the script section. The basic structure is shown in the screenshot below:


Figure 14 - HTML form: script sectionFigure 14 - HTML form: script section

 

  • The script begins by defining global variables. Variables with an underscore prefix store parameters received from the VA dashboard, while the model parameter holds the name of the selected model when a form button is clicked.

  • The script then listens for the DOMContentLoaded event to ensure the DOM is fully loaded before executing the code. This is a best practice when working with JavaScript. When the event occurs, the onDataReceived callback function is triggered, which processes the data received from the VA dashboard. Specifically, it verifies if:

    • At least one column and one row are passed to the DDC object.
    • All necessary parameters are defined in the VA dashboard.

If both conditions are met, the model selection buttons are enabled.

  • When a model button is clicked, the trainModel function is called with the model name as an argument. This function initiates a job via the callJob function and displays the job’s execution status in the jobResults section.

  • The callJob function prepares a form data object with necessary parameters, including the selected model and other VA-specific parameters, sending it via an HTTP call. The job is called with the _action parameter set to json. This results in the job response being a list in JSON format of output files created by the job. From the list, the files’ content can be retrieved using the URIs specified in the HREF keys (for more details, see here). The response is then processed to display a success or error message in the jobResults section:

    • If unexpected execution errors occur, the error information is returned in a JSON structure with the following fields (according to the documentation)​:


      Figure 15 - Example of JSON response when there is an error in the SAS codeFigure 15 - Example of JSON response when there is an error in the SAS code


      In this case, an error message is displayed in the DDC object, prompting the user to check the browser’s developer console, where the request response and the SAS® log are displayed to identify the lines in the SAS® code causing the error. The SAS® log is retrieved and processed by the obtainSASLogLines function to extract only log lines.
    • If no execution errors are found, the _appout.json file is inspected using the obtainAppExecutionInfo function to ensure no application-level errors exist (e.g., all input parameters are present, and the CAS table exists).
    • If both checks pass, a “Done!” message is displayed in the DDC object for 2 seconds before disappearing.

 

How to deploy this project

Prerequisites:

  • As previously mentioned, the Chronos model should be deployed on the same Kubernetes Cluster as your SAS® Viya installation. For a detailed step-by-step procedure, please refer to this article
  • For running the Chronos model with PROC TSMODEL, the EXTLANG package should be installed and configured, ensuring that numpy and requests are included in the setup.

Deployment steps:

  1. Download the zip file attached to the article. Additionally, the same files are available for download from this GitHub repository, under the folder named ModelComparison.

  2. Open the SAS® Job Execution web application by navigating to http://<your.host.name>/SASJobExecution/.

  3. Create two new JavaScript files in a folder of your choice by using the New File option and selecting the appropriate File type. The steps are shown in the screenshot below.


    Figure 16 - Creating a JavaScript file in SAS Job Execution Web applicationFigure 16 - Creating a JavaScript file in SAS Job Execution Web application

     

    Name the files as follows and paste the corresponding content from the GitHub repository’s util folder:

    • contentUtil.js
    • messagingUtil.js
    This ensures the files are correctly loaded as JavaScript files. They will be included in the HTML form, as already seen in the corresponding section.
  4. Create a new job in your preferred folder and give it a name. Follow a similar procedure as in the previous step.

    Figure 17 - Creating a SAS Job in SAS Job Execution Web applicationFigure 17 - Creating a SAS Job in SAS Job Execution Web application

  5. Right-click on the job, select Properties, then navigate to Parameters and add a new parameter with the following details:

    • Name: _action
    • Default value: FORM
    • Leave all other settings as default.

     

    Setting _action to FORM (case-insensitive) causes the SAS® Job Execution Web application to transfer execution to the HTML form, which then calls the SAS® code stored in the job (with _action=JSON).
  6. Save the changes made to the job.
  7. Right-click on the job and choose Edit > Source code. Copy and paste the contents of the ModelComparison.sas file.
  8. Replace the CHRONOS_ENDPOINT value with your specific Chronos endpoint:

    Figure 18 - Code line for Chronos endpoint to updateFigure 18 - Code line for Chronos endpoint to update

     

  9. Save the job after editing the source code.
  10. Right-click on the job, select Edit > New HTML form, and copy-paste the content from the ModelComparison.html file.
  11. Update the path of the JavaScript files. To get them, right-click on the files and select Properties. Here is an example for the contentUtil.js file:

    Figure 19 - Obtaining JavaScript files' full pathFigure 19 - Obtaining JavaScript files' full path

     

    Replace the path after the equal sign in each of the following lines with the paths to your own files:

    Figure 20 - Modifying src with your JavaScript files' full pathFigure 20 - Modifying src with your JavaScript files' full path
  12. Pre-process your input dataset using the preprocessing.sas file. If needed, customize the values of the five macro variables (originaltab, castab, target, date, byvar) in the first few lines of the code before running it.
    Note: Be sure that all the variables types and formats are correct in your input dataset. For example, verify that your date variable has a date format, otherwise it will be considered by Visual Analytics as a numeric variable.
  13. Go to http://<your.host.name>/SASVisualAnalytics/ and log in.
  14. Create a new empty report in SAS® Visual Analytics.
  15. With the report open, press Ctrl+Alt+B to open the SAS® Visual Analytics Diagnostics window.
  16. Replace the existing XML content with the content from the ModelComparison.xml file.
  17. Click Load to apply the XML content.
  18. First off, add your pre-processed CAS table in the Data pane on the left-hand side:

    Figure 21 - Adding data to the VA dashboardFigure 21 - Adding data to the VA dashboard
  19. In the Parameter section of the Data pane on the left-hand side, modify the following parameters:

    • _job_cas_table: Set this to match the value of the castab macro variable in preprocessing.sas.
    • _target: Set this to match the value of the target macro variable in preprocessing.sas.
    • _date: Set this to match the value of the date macro variable in preprocessing.sas.
    • _byvar: Set this to match the value of the byvar macro variable in preprocessing.sas.
    • _date_interval: Specify the frequency of the accumulated time series (e.g., year, month, quarter, week). Refer to the documentation for a summary of interval types for SAS® date values.
    • _end_historical_data: Use this to display only the forecasted values for the forecast horizon. Set it to the last date value for which you have data.

    Note: The parameters _by_variable and _variable_name_parameter do not need modification, as they are automatically set by the Drop-down list control and the List control objects, respectively.

  20. Assign the following Data Roles, Display Rules and Filters to the report objects:
    • List
      • Category: Variable name.
      • Filters. Click New filter > Advanced filter and copy-paste the following expression:
        'Variable name'n = UpCase(_target) OR
        (IF _by_variable = '.'
            RETURN StartsWith('Variable name'n, 'forecasted') AND 'Sales Region'n = '.'
        ELSE StartsWith('Variable name'n, 'forecasted') AND 'Sales Region'n = _by_variable)

        Substitute 'Sales Region'n with your BY variable both at the end of line 3 and 4.

      • Options: Replace the Initial value for the control with the name of your target variable in uppercase:

        Figure 22 - Changing required initial value for List control objectFigure 22 - Changing required initial value for List control object

         

    • Time Series Plot.
      • Time axis: your date variable.
      • Measure: remove Frequency and add Variable value.
      • Group: Variable Name. 
      • Display Rules:

        Figure 23 - Display rules for the Time Series plotFigure 23 - Display rules for the Time Series plot
        Compared to the screenshot, you only need to substitute SALE with your target variable's name in upper case, which should be actually prompted to you after writing the first letter.
        Of course, the color choice can be modified based on your taste.
      • Filters. Click New filter > Advanced filter and copy-paste the following expression:
        'Variable name'n = UpCase(_target) OR
        (IF _by_variable = '.'
            RETURN StartsWith('Variable name'n, 'forecasted') AND
                   In('Variable name'n, _variable_name_parameter) AND
                   'Sales Region'n = '.' AND
                   'Order Date'n > _end_historical_data
        ELSE StartsWith('Variable name'n, 'forecasted') AND
             In('Variable name'n, _variable_name_parameter) AND
             'Sales Region'n = _by_variable AND
             'Order Date'n > _end_historical_data)

        Also in this case, replace 'Sales Region'n with your BY variable at the beginning of lines 5 and 9, and 'Order Date'n with your date variable at the beginning of lines 6 and 10.

    • Data-driven Content.
      • Variables: Variable name.
      • Filters. Click New filter > Advanced filter and copy-paste the following expression:
        (_job_cas_table = _job_cas_table) AND (_by_variable = _by_variable) AND (_target = _target) AND (_date = _date) AND (_byvar = _byvar) AND (_date_interval = _date_interval)​
        The reason of this dummy advanced filter (that always returns true) is that VA parameters are only passed in the JSON message to the DDC if the parameters affect the data that is being passed to the DDC (as explained in this article). 
    • Drop-down List.
      • Category: your BY variable.
      • Filters. Click New filter > Advanced filter and copy-paste the following expression:
        ('Sales Region'n) <> ('.')​
        Substitute 'Sales Region'n with your BY variable.
  21. Select the DDC object in the report, then go to the Options pane on the right. Replace the URL with the one found in the job’s Properties > Details pane:

    Figure 24 - Obtaining SAS Job URLFigure 24 - Obtaining SAS Job URL
  22. Save the report after making all changes.

 

Conclusion

In conclusion, the integration of foundation models into the realm of time series forecasting marks a significant advancement in the field. As foundation models continue to evolve, their application in time series forecasting will likely expand, offering even more effective solutions in the future.
With the DDC object described in this article, you can easily train and compare Time Series Foundation Models (TSFMs) like Chronos with traditional forecasting techniques using a VA dashboard. This allows you to evaluate their performance on your specific datasets. The models shown here are just examples, and you can customize the solution to include your preferred models and additional variables. Feel free to use this article as a starting point to create your own tailored version! 😊

 

Acknowledgements

I would like to express my sincere gratitude to Arpit Jain and David Weik for the opportunity to work on this project and for our discussions and idea exchanges, which led to the final outcome.
I also want to thank Iman Vasheghani Farahani for his assistance with questions regarding the TSMODEL procedure, as well as Michael Carman and Renato Luppi for their guidance in incorporating JavaScript files into the HTML form.

 

References

  • To start understanding how to use the DDC Object in Visual Analytics, the four-part series of articles beginning with this one is really enlightening!
  • The series of articles starting with this one, along with this one, inspired me to create the basic structure for my SAS® Job.
  • For more information on how to deploy image, CSS and JavaScript files in the SAS® Content Server and add them to the HTML form, check out this article.
  • I found this article really helpful for understanding how to build custom models in PROC TSMODEL. Another valuable resource is this one, which outlines all the steps to fit a model using the Time Series Model (TSM) Package in the TSMODEL Procedure.
  • For more information on CAS Actions, check out CAS Action! - a series on fundamentals - SAS Viya Programming.
Version history
Last update:
‎09-04-2024 05:11 AM
Updated by:
Contributors

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started

Article Tags