Auto Ml Forecasting Backtest Many Models
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
![]()
Many Models with Backtesting - Automated ML
Backtest many models time series forecasts with Automated Machine Learning
For this notebook we are using a synthetic dataset to demonstrate the back testing in many model scenario. This allows us to check historical performance of AutoML on a historical data. To do that we step back on the backtesting period by the data set several times and split the data to train and test sets. Then these data sets are used for training and evaluation of model.
Thus, it is a quick way of evaluating AutoML as if it was in production. Here, we do not test historical performance of a particular model, for this see the notebook. Instead, the best model for every backtest iteration can be different since AutoML chooses the best model for a given training set.

NOTE: There are limits on how many runs we can do in parallel per workspace, and we currently recommend to set the parallelism to maximum of 320 runs per experiment per workspace. If users want to have more parallelism and increase this limit they might encounter Too Many Requests errors (HTTP 429).
Prerequisites
You'll need to create a compute Instance by following these instructions.
1.0 Set up workspace, datastore, experiment
This notebook is compatible with Azure ML SDK version 1.35.1 or later.
Choose an experiment
2.0 Data
2.1 Data generation
For this notebook we will generate the artificial data set with two time series IDs. Then we will generate backtest folds and will upload it to the default BLOB storage and create a TabularDataset
Now we will generate 8 backtesting folds with backtesting period of 7 days and with the same forecasting horizon. We will add the column "backtest_iteration", which will identify the backtesting period by the last training date.
2.2 Create the Tabular Data Set.
A Datastore is a place where data can be stored that is then made accessible to a compute either by means of mounting or copying the data to the compute target.
Please refer to Datastore documentation on how to access data from Datastore.
In this next step, we will upload the data and create a TabularDataset.
3.0 Build the training pipeline
Now that the dataset, WorkSpace, and datastore are set up, we can put together a pipeline for training.
Note that if you have an AzureML Data Scientist role, you will not have permission to create compute resources. Talk to your workspace or IT admin to create the compute targets described in this section, if they do not already exist.
Choose a compute target
You will need to create a compute target for your AutoML run. In this tutorial, you create AmlCompute as your training compute resource.
**Creation of AmlCompute takes approximately 5 minutes.**
If the AmlCompute with that name is already in your workspace this code will skip the creation process. As with other Azure services, there are limits on certain resources (e.g. AmlCompute) associated with the Azure Machine Learning service. Please read this article on the default limits and how to request more quota.
Set up training parameters
We need to provide ForecastingParameters, AutoMLConfig and ManyModelsTrainParameters objects. For the forecasting task we also need to define several settings including the name of the time column, the maximum forecast horizon, and the partition column name(s) definition.
ForecastingParameters arguments
| Property | Description |
|---|---|
| forecast_horizon | The forecast horizon is how many periods forward you would like to forecast. This integer horizon is in units of the timeseries frequency (e.g. daily, weekly). Periods are inferred from your data. |
| time_column_name | The name of your time column. |
| time_series_id_column_names | The column names used to uniquely identify timeseries in data that has multiple rows with the same timestamp. |
| cv_step_size | Number of periods between two consecutive cross-validation folds. The default value is "auto", in which case AutoMl determines the cross-validation step size automatically, if a validation set is not provided. Or users could specify an integer value. |
AutoMLConfig arguments
| Property | Description |
|---|---|
| task | forecasting |
| primary_metric | This is the metric that you want to optimize. Forecasting supports the following primary metrics spearman_correlation normalized_root_mean_squared_error r2_score normalized_mean_absolute_error |
| blocked_models | Blocked models won't be used by AutoML. |
| iteration_timeout_minutes | Maximum amount of time in minutes that the model can train. This is optional but provides customers with greater control on exit criteria. |
| iterations | Number of models to train. This is optional but provides customers with greater control on exit criteria. |
| experiment_timeout_hours | Maximum amount of time in hours that each experiment can take before it terminates. This is optional but provides customers with greater control on exit criteria. It does not control the overall timeout for the pipeline run, instead controls the timeout for each training run per partitioned time series. |
| label_column_name | The name of the label column. |
| n_cross_validations | Number of cross validation splits. The default value is "auto", in which case AutoMl determines the number of cross-validations automatically, if a validation set is not provided. Or users could specify an integer value. Rolling Origin Validation is used to split time-series in a temporally consistent way. |
| enable_early_stopping | Flag to enable early termination if the primary metric is no longer improving. |
| enable_engineered_explanations | Engineered feature explanations will be downloaded if enable_engineered_explanations flag is set to True. By default it is set to False to save storage space. |
| track_child_runs | Flag to disable tracking of child runs. Only best run is tracked if the flag is set to False (this includes the model and metrics of the run). |
| pipeline_fetch_max_batch_size | Determines how many pipelines (training algorithms) to fetch at a time for training, this helps reduce throttling when training at large scale. |
ManyModelsTrainParameters arguments
| Property | Description |
|---|---|
| automl_settings | The AutoMLConfig object defined above. |
| partition_column_names | The names of columns used to group your models. For timeseries, the groups must not split up individual time-series. That is, each group must contain one or more whole time-series. |
Set up many models pipeline
Parallel run step is leveraged to train multiple models at once. To configure the ParallelRunConfig you will need to determine the appropriate number of workers and nodes for your use case. The process_count_per_node is based off the number of cores of the compute VM. The node_count will determine the number of master nodes to use, increasing the node count will speed up the training process.
| Property | Description |
|---|---|
| experiment | The experiment used for training. |
| train_data | The file dataset to be used as input to the training run. |
| node_count | The number of compute nodes to be used for running the user script. We recommend to start with 3 and increase the node_count if the training time is taking too long. |
| process_count_per_node | Process count per node, we recommend 2:1 ratio for number of cores: number of processes per node. eg. If node has 16 cores then configure 8 or less process count per node or optimal performance. |
| train_pipeline_parameters | The set of configuration parameters defined in the previous section. |
| run_invocation_timeout | Maximum amount of time in seconds that the ParallelRunStep class is allowed. This is optional but provides customers with greater control on exit criteria. This must be greater than experiment_timeout_hours by at least 300 seconds. |
Calling this method will create a new aggregated dataset which is generated dynamically on pipeline execution.
Note: Total time taken for the training step in the pipeline to complete = $ \frac{t}{ p \times n } \times ts $ where,
- $ t $ is time taken for training one partition (can be viewed in the training logs)
- $ p $ is
process_count_per_node - $ n $ is
node_count - $ ts $ is total number of partitions in time series based on
partition_column_names
Submit the pipeline to run
Next we submit our pipeline to run. The whole training pipeline takes about 20 minutes using a STANDARD_DS12_V2 VM with our current ParallelRunConfig setting.
Check the run status, if training_run is in completed state, continue to next section. Otherwise, check the portal for failures.
4.0 Backtesting
Now that we selected the best AutoML model for each backtest fold, we will use these models to generate the forecasts and compare with the actuals.
Set up output dataset for inference data
Output of inference can be represented as OutputFileDatasetConfig object and OutputFileDatasetConfig can be registered as a dataset.
For many models we need to provide the ManyModelsInferenceParameters object.
ManyModelsInferenceParameters arguments
| Property | Description |
|---|---|
| partition_column_names | List of column names that identifies groups. |
| target_column_name | [Optional] Column name only if the inference dataset has the target. |
| time_column_name | [Optional] Time column name only if it is timeseries. |
| inference_type | [Optional] Which inference method to use on the model. Possible values are 'forecast', 'predict_proba', and 'predict'. |
| forecast_mode | [Optional] The type of forecast to be used, either 'rolling' or 'recursive'; defaults to 'recursive'. |
| step | [Optional] Number of periods to advance the forecasting window in each iteration (for rolling forecast only); defaults to 1. |
get_many_models_batch_inference_steps arguments
| Property | Description |
|---|---|
| experiment | The experiment used for inference run. |
| inference_data | The data to use for inferencing. It should be the same schema as used for training. |
| compute_target | The compute target that runs the inference pipeline. |
| node_count | The number of compute nodes to be used for running the user script. We recommend to start with the number of cores per node (varies by compute sku). |
| process_count_per_node | [Optional] The number of processes per node. By default it's 2 (should be at most half of the number of cores in a single node of the compute cluster that will be used for the experiment). |
| inference_pipeline_parameters | [Optional] The ManyModelsInferenceParameters object defined above. |
| append_row_file_name | [Optional] The name of the output file (optional, default value is 'parallel_run_step.txt'). Supports 'txt' and 'csv' file extension. A 'txt' file extension generates the output in 'txt' format with space as separator without column names. A 'csv' file extension generates the output in 'csv' format with comma as separator and with column names. |
| train_run_id | [Optional] The run id of the training pipeline. By default it is the latest successful training pipeline run in the experiment. |
| train_experiment_name | [Optional] The train experiment that contains the train pipeline. This one is only needed when the train pipeline is not in the same experiement as the inference pipeline. |
| run_invocation_timeout | [Optional] Maximum amount of time in seconds that the ParallelRunStep class is allowed. This is optional but provides customers with greater control on exit criteria. |
| output_datastore | [Optional] The Datastore or OutputDatasetConfig to be used for output. If specified any pipeline output will be written to that location. If unspecified the default datastore will be used. |
| arguments | [Optional] Arguments to be passed to inference script. Possible argument is '--forecast_quantiles' followed by quantile values. |
5.0 Retrieve results and calculate metrics
The pipeline returns one file with the predictions for each times series ID and outputs the result to the forecasting_output Blob container. The details of the blob container is listed in 'forecasting_output.txt' under Outputs+logs.
The next code snippet does the following:
- Downloads the contents of the output folder that is passed in the parallel run step
- Reads the parallel_run_step.txt file that has the predictions as pandas dataframe
- Saves the table in csv format and
- Displays the top 10 rows of the predictions
View metrics
We will read in the obtained results and run the helper script, which will generate metrics and create the plots of predicted versus actual values.
The directory contains a set of files with results:
- forecast.csv contains forecasts for all backtest iterations. The backtest_iteration column contains iteration identifier with the last training date as a suffix
- scores.csv contains all metrics. If data set contains several time series, the metrics are given for all combinations of time series id and iterations, as well as scores for all iterations and time series ids, which are marked as "all_sets"
- plots_fcst_vs_actual.pdf contains the predictions vs forecast plots for each iteration and, eash time series is saved as separate plot.
For demonstration purposes we will display the table of metrics for one of the time series with ID "ts0". We will create the utility function, which will build the table with metrics.
Forecast vs actuals plots.