Auto Ml Forecasting Many Models
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the MIT License.
![]()
!Important!
This notebook is outdated and is not supported by the AutoML Team. Please use the supported version (link).
Many Models - Automated ML
Generate many models time series forecasts with Automated Machine Learning
For this notebook we are using a synthetic dataset portraying sales data to predict the the quantity of a vartiety of product skus across several states, stores, and product categories.
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
Choose an experiment
2.0 Data
This notebook uses simulated orange juice sales data to walk you through the process of training many models on Azure Machine Learning using Automated ML.
The time series data used in this example was simulated based on the University of Chicago's Dominick's Finer Foods dataset which featured two years of sales of 3 different orange juice brands for individual stores. The full simulated dataset includes 3,991 stores with 3 orange juice brands each thus allowing 11,973 models to be trained to showcase the power of the many models pattern.
In this notebook, two datasets will be created: one with all 11,973 files and one with only 10 files that can be used to quickly test and debug. For each dataset, you'll be walked through the process of:
- Registering the blob container as a Datastore to the Workspace
- Registering a tabular dataset to the Workspace
2.1 Data Preparation
The OJ data is available in the public blob container. The data is split to be used for training and for inferencing. For the current dataset, the data was split on time column ('WeekStarting') before and after '1992-5-28' .
The container has
- 'oj-data-tabular' and 'oj-inference-tabular' folders that contains training and inference data respectively for the 11,973 models.
- It also has 'oj-data-small-tabular' and 'oj-inference-small-tabular' folders that has training and inference data for 10 models.
To create the TabularDataset needed for the ParallelRunStep, you first need to register the blob container to the workspace.
To use your own data, put your own data in a blobstore folder. As shown it can be one file or multiple files. We can then register datastore using that blob as shown below.
How sample data in blob store looks like

2.2 Register the blob container as DataStore
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 be registering blob storage as datastore to the Workspace.
2.3 Using tabular datasets
Now that the datastore is available from the Workspace, TabularDataset can be created. Datasets in Azure Machine Learning are references to specific data in a Datastore. We are using TabularDataset, so that users who have their data which can be in one or many files (*.parquet or *.csv) and have not split up data according to group columns needed for training, can do so using out of box support for 'partiion_by' feature of TabularDataset shown in section 5.0 below.
2.4 Configure data with OutputFileDatasetConfig objects
This step shows how to configure output data from a pipeline step. One of the use cases for this step is when you want to do some preprocessing before feeding the data to training step. Intermediate data (or output of a step) is represented by an OutputFileDatasetConfig object. output_data is produced as the output of a step. Optionally, this data can be registered as a dataset by calling the register_on_complete method. If you create an OutputFileDatasetConfig in one step and use it as an input to another step, that data dependency between steps creates an implicit execution order in the pipeline.
OutputFileDatasetConfig objects return a directory, and by default write output to the default datastore of the workspace.
Since instance creation for class OutputTabularDatasetConfig is not allowed, we first create an instance of this class. Then we use the read_parquet_files method to read the parquet file into OutputTabularDatasetConfig.
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.
Configure the training run's environment
The next step is making sure that the remote training run has all the dependencies needed by the training steps. Dependencies and the runtime context are set by creating and configuring a RunConfiguration object.
The code below shows two options for handling dependencies. As presented, with USE_CURATED_ENV = True, the configuration is based on a curated environment. Curated environments have prebuilt Docker images in the Microsoft Container Registry. For more information, see Azure Machine Learning curated environments.
The path taken if you change USE_CURATED_ENV to False shows the pattern for explicitly setting your dependencies. In that scenario, a new custom Docker image will be created and registered in an Azure Container Registry within your resource group (see Introduction to private Docker container registries in Azure). Building and registering this image can take quite a few minutes.
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. |
Construct your pipeline steps
Once you have the compute resource and environment created, you're ready to define your pipeline's steps. There are many built-in steps available via the Azure Machine Learning SDK, as you can see on the reference documentation for the azureml.pipeline.steps package. The most flexible class is PythonScriptStep, which runs a Python script.
Your data preparation code is in a subdirectory (in this example, "data_preprocessing_tabular.py" in the directory "./scripts"). As part of the pipeline creation process, this directory is zipped and uploaded to the compute_target and the step runs the script specified as the value for script_name.
The arguments values specify the inputs and outputs of the step. In the example below, the baseline data is the input_ds_small dataset. The script data_preprocessing_tabular.py does whatever data-transformation tasks are appropriate to the task at hand and outputs the data to output_data, of type OutputFileDatasetConfig. For more information, see Moving data into and between ML pipeline steps (Python). The step will run on the machine defined by compute_target, using the configuration aml_run_config.
Reuse of previous results (allow_reuse) is key when using pipelines in a collaborative environment since eliminating unnecessary reruns offers agility. Reuse is the default behavior when the script_name, inputs, and the parameters of a step remain the same. When reuse is allowed, results from the previous run are immediately sent to the next step. If allow_reuse is set to False, a new run will always be generated for this step during pipeline execution.
Note that we only support partitioned FileDataset and TabularDataset without partition when using such output as input.
Note that we drop column "Revenue" from the dataset in this step to avoid information leak as "Quantity" = "Revenue" / "Price". Please modify the logic based on your data.
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 for 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 40m using a STANDARD_D16S_V3 VM with our current ParallelRunConfig setting.
Check the run status, if training_run is in completed state, continue to forecasting. If training_run is in another state, check the portal for failures.
5.0 Publish and schedule the train pipeline (Optional)
5.1 Publish the pipeline
Once you have a pipeline you're happy with, you can publish a pipeline so you can call it programmatically later on. See this tutorial for additional information on publishing and calling pipelines.
5.2 Schedule the pipeline
You can also schedule the pipeline to run on a time-based or change-based schedule. This could be used to automatically retrain models every month or based on another trigger such as data drift.
6.0 Forecasting
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. |
Retrieve results
The forecasting pipeline forecasts the orange juice quantity for a Store by Brand. The pipeline returns one file with the predictions for each store 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 following code snippet:
- Downloads the contents of the output folder that is passed in the parallel run step
- Reads the output file that has the predictions as pandas dataframe and
- Displays the top 10 rows of the predictions
7.0 Publish and schedule the inference pipeline (Optional)
7.1 Publish the pipeline
Once you have a pipeline you're happy with, you can publish a pipeline so you can call it programmatically later on. See this tutorial for additional information on publishing and calling pipelines.
7.2 Schedule the pipeline
You can also schedule the pipeline to run on a time-based or change-based schedule. This could be used to automatically retrain or forecast models every month or based on another trigger such as data drift.


