Greykite Library

Greykite Info

  • Overview

Quick Start

  • Quickstart
    • Simple Forecast
    • Data exploration
    • Interpretability
    • Grid Search and Benchmarking
      • Grid Search
        • Grid search hyperparameters
        • Selective grid search
      • Benchmarking
    • Reconciliation
  • Tutorials
  • Model Templates

Step by Step

  • Forecasting Process
  • Choose a Model
  • Choose a Model Template
  • Examine Input Data
  • Configure a Forecast
  • Check Forecast Result
  • Debugging

Tuning the Model Components

  • Greykite models and components
  • Growth
  • Seasonality
  • Holidays and Events
  • Changepoints
  • Custom Parameters
  • Regressors
  • Auto-regression
  • Uncertainty Intervals
  • Pre-processing, Selective Grid Search

Benchmarking

  • Benchmarking

Miscellaneous

  • Reconcile Forecasts
  • Model store and load

Changelog

  • 0.5.0 (2023-04-03)
  • 0.4.0 (2022-07-15)
  • 0.3.0 (2021-12-14)
  • 0.2.0 (2021-06-30)
  • 0.1.1 (2021-05-12)

API Reference

  • Docs
Greykite Library
  • Quickstart
  • Grid Search

Note

Click here to download the full example code

Grid Search

Forecast models have many hyperparameters that could significantly affect the accuracy. These hyperparameters control different components in the model including trend, seasonality, events, etc. You can learn more about how to configure the components or hyperparameters in the model tuning tutorial (Tune your first forecast model). Here we will see a step-by-step example of how to utilize the “grid search” functionality to choose the best set of hyperparameters.

All model templates support grid search. Here we continue the model tuning tutorial example to use the SILVERKITE model on the Peyton Manning data set. The mechanism of using grid search in PROPHET is similar.

19 import warnings
20
21 warnings.filterwarnings("ignore")
22
23 from greykite.common.data_loader import DataLoader
24 from greykite.common.evaluation import EvaluationMetricEnum
25 from greykite.framework.templates.autogen.forecast_config import ComputationParam
26 from greykite.framework.templates.autogen.forecast_config import EvaluationMetricParam
27 from greykite.framework.templates.autogen.forecast_config import EvaluationPeriodParam
28 from greykite.framework.templates.autogen.forecast_config import ForecastConfig
29 from greykite.framework.templates.autogen.forecast_config import ModelComponentsParam
30 from greykite.framework.templates.forecaster import Forecaster
31 from greykite.framework.templates.model_templates import ModelTemplateEnum
32 from greykite.framework.utils.result_summary import summarize_grid_search_results
33
34 # Loads dataset into pandas DataFrame
35 dl = DataLoader()
36 df = dl.load_peyton_manning()

Grid search hyperparameters

In Tune your first forecast model we learned how the components affect the prediction and how to choose the potential candidate components. We also learned how to interpret the cross-validation results for one set of hyperparameters. In this section, we will go over the grid_search functionality that allows us to compare different sets of hyperparameters by running cross-validation on them automatically.

In the ModelComponentsParam class, each attribute contains a dictionary mapping parameter names to parameter values. You may specify either a specific parameter value to use, or a list of values to explore via grid search. Grid search is done over every possible combination of hyperparameters across the lists.

Note

You may only provide lists for these attributes’ parameter values, not for the parameter values of these attributes’ parameter values if they are dictionaries. For example, seasonality is an attribute in ModelComponentsParam, which has parameter names yearly_seasonality, quarterly_seasonality, etc. We can provide lists for the parameter values of these names. On the other hand, changepoints is an attribute, too, which has parameter names changepoints_dict and seasonality_changepoints_dict. Both names take dictionaries as their parameter values. We can provide lists of dictionaries as the values, however, within each dictionary, we are not allowed to further wrap parameters in lists.

Cross-validation will be performed over these sets of hyperparameters, and the best set of hyperparameters will be selected based on the metric you pick, specified by cv_selection_metric in EvaluationMetricParam.

Now consider that we want to compare different yearly seasonalities (10 or 20), trend changepoints (None or “auto”) and fit algorithms (linear or ridge), while keeping all other model components the same. We could specify:

 73 seasonality = {
 74     "yearly_seasonality": [10, 20],  # yearly seasonality could be 10 or 20
 75     "quarterly_seasonality": False,
 76     "monthly_seasonality": False,
 77     "weekly_seasonality": False,
 78     "daily_seasonality": False
 79 }
 80
 81 changepoints = {
 82     # Changepoints could be None or auto.
 83     "changepoints_dict": [
 84         None,
 85         {"method": "auto"}
 86     ]
 87 }
 88
 89 # Specifies custom parameters
 90 custom = {
 91     "fit_algorithm_dict": [
 92         {"fit_algorithm": "ridge"},
 93         {"fit_algorithm": "linear", "fit_algorithm_params": dict(missing="drop")}
 94     ]
 95 }
 96
 97 # Specifies the model components
 98 # Could leave the other components as default,
 99 # or specify them in the normal way.
100 model_components = ModelComponentsParam(
101     seasonality=seasonality,
102     changepoints=changepoints,
103     custom=custom
104 )
105
106 # Specifies the metrics
107 evaluation_metric = EvaluationMetricParam(
108     # The metrics in ``cv_report_metrics`` will be calculated and reported.
109     cv_report_metrics=[EvaluationMetricEnum.MeanAbsolutePercentError.name,
110                        EvaluationMetricEnum.MeanSquaredError.name],
111     # The ``cv_selection_metric`` will be used to select the best set of hyperparameters.
112     # It will be added to ``cv_report_metrics`` if it's not there.
113     cv_selection_metric=EvaluationMetricEnum.MeanAbsolutePercentError.name
114 )
115
116 # Specifies the forecast configuration.
117 # You could also specify ``forecast_horizon``, ``metadata_param``, etc.
118 config = ForecastConfig(
119     model_template=ModelTemplateEnum.SILVERKITE.name,
120     model_components_param=model_components,
121     evaluation_metric_param=evaluation_metric
122 )

For the configuration above, all other model components parameters are the same but yearly seasonality, changepoints and fit algorithm have 2 options each. The model will automatically run cross-validation over the 8 cases:

  • yearly seasonality = 10, no changepoints, fit algorithm = “linear”.

  • yearly seasonality = 20, no changepoints, fit algorithm = “linear”.

  • yearly seasonality = 10, automatic changepoints, fit algorithm = “linear”.

  • yearly seasonality = 20, automatic changepoints, fit algorithm = “linear”.

  • yearly seasonality = 10, no changepoints, fit algorithm = “ridge”.

  • yearly seasonality = 20, no changepoints, fit algorithm = “ridge”.

  • yearly seasonality = 10, automatic changepoints, fit algorithm = “ridge”.

  • yearly seasonality = 20, automatic changepoints, fit algorithm = “ridge”.

The CV test scores will be reported for all 8 cases using the metrics in cv_report_metrics, and the final model will be trained on the best set of hyperparameters according to the cv_selection_metric.

Selective grid search

Consider the case when you have 6 model components to tune, each with 3 different candidates. In this case, there will be 3^6=729 different sets of hyperparameters to grid search from. The results might be convincing because of the exhaustive grid search, however, the running time is going to pile up.

It’s very common that not all of the 729 sets of hyperparameters makes sense to us, so it would be good not to run all of them. There are two ways to do selective grid search:

  • Setting hyperparameter_budget.

  • Utilizing hyperparameter_override.

Setting hyperparameter_budget

The hyperparameter_budget parameter directly controls how many sets of hyperparameters will be used in grid search. If this number is less than the number of all possible sets of hyperparameters, the algorithm will randomly pick hyperparameter_budget number of hyperparameter sets. Set hyperparameter_budget to -1 to search all possible sets. You may set the budget in the ComputationParam class. This is a simple way to search a large space of hyperparameters if you are not sure which are likely to succeed. After you identify parameter values with better performance, you may run a more precise grid search to fine tune around these values.

Note

If you have a small number of timeseries to forecast, we recommend using the model tuning tutorial (Tune your first forecast model) to help identify good parameters candidates. This is likely more effective than random grid search over a large grid.

172 # Specifies the hyperparameter_budget.
173 # Randomly picks 3 sets of hyperparameters.
174 computation = ComputationParam(
175     hyperparameter_budget=3
176 )
177 # Specifies the forecast configuration.
178 # You could also specify ``forecast_horizon``, ``metadata_param``, etc.
179 config = ForecastConfig(
180     model_template=ModelTemplateEnum.SILVERKITE.name,
181     model_components_param=model_components,
182     evaluation_metric_param=evaluation_metric,
183     computation_param=computation
184 )

Utilizing hyperparameter_override

The hyperparameter_override functionality allows us to customize the sets of hyperparameters to search within. The way is to specify the hyperparameter_override parameter in the ModelComponentsParam class. First, model components are translated to the parameters in the corresponding sklearn Estimator for the template (SimpleSilverkiteEstimator and ProphetEstimator). The name is usually the same as the key, for example, “estimator__yearly_seasonality” and “estimator__fit_algorithm_dict” (the ModelComponentsParam attribute is ignored). This creates a default hyperparameter_grid dictionary. Then for each dict in hyperparameter_override, the default grid’s values are replaced by the override values, producing a list of customized grids to search over. Grid search done across all the grids in the list. For more details, see hyperparameter override. Now assume we have the following parameter options, as above:

  • yearly seasonality orders: 10 and 20.

  • trend changepoints: None and “auto”.

  • fit algorithm: linear and ridge.

We do not want to run all 8 sets of hyperparameters. For example, we think that ridge is not needed for the model without changepoints because the model is simple, while linear should not be used when there are changepoints because the model is complex. So we want:

  • for no changepoints we use linear regression only.

  • for automatic changepoints we use ridge regression only.

Then we can specify:

216 seasonality = {
217     "yearly_seasonality": [10, 20],
218     "quarterly_seasonality": False,
219     "monthly_seasonality": False,
220     "weekly_seasonality": False,
221     "daily_seasonality": False
222 }
223
224 changepoints = {
225     "changepoints_dict": None
226 }
227
228 # Specifies custom parameters
229 custom = {
230     "fit_algorithm_dict": {"fit_algorithm": "linear"}
231 }
232
233 # Hyperparameter override can be a list of dictionaries.
234 # Each dictionary will be one set of hyperparameters.
235 override = [
236     {},
237     {
238         "estimator__changepoints_dict": {"method": "auto"},
239         "estimator__fit_algorithm_dict": {"fit_algorithm": "ridge"}
240     }
241 ]
242
243 # Specifies the model components
244 # Could leave the other components as default,
245 # or specify them in the normal way.
246 model_components = ModelComponentsParam(
247     seasonality=seasonality,
248     changepoints=changepoints,
249     custom=custom,
250     hyperparameter_override=override
251 )
252
253 # Specifies the evaluation period
254 evaluation_period = EvaluationPeriodParam(
255     test_horizon=365,             # leaves 365 days as testing data
256     cv_horizon=365,               # each CV test size is 365 days (same as forecast horizon)
257     cv_max_splits=3,              # 3 folds CV
258     cv_min_train_periods=365 * 4  # uses at least 4 years for training because we have 8 years data
259 )
260
261 config = ForecastConfig(
262     forecast_horizon=365,
263     model_template=ModelTemplateEnum.SILVERKITE.name,
264     model_components_param=model_components,
265     evaluation_metric_param=evaluation_metric,
266     evaluation_period_param=evaluation_period
267 )

The forecast configuration above specifies the yearly seasonality orders in a list, therefore, both 10 and 20 will be searched. For the hyperparameter override list, there are two elements. The first one is an empty dictionary, which corresponds to the original changepoint and fit algorithm in the configuration. The second dictionary overrides changepoint method with automatic changepoint detection and fit algorithm with ridge. In total, the model will run 4 different configurations:

  • yearly seasonality 10, no changepoint, fit algorithm linear.

  • yearly seasonality 20, no changepoint, fit algorithm linear.

  • yearly seasonality 10, automatic changepoints, fit algorithm ridge.

  • yearly seasonality 20, automatic changepoints, fit algorithm ridge.

In this way, we could only search the sets of hyperparameters we need and save a lot of time. Also note that the above configuration also configures the CV splits using EvaluationPeriodParam. We can see the configs and evaluations with summarize_grid_search_results.

287 # Runs the forecast
288 forecaster = Forecaster()
289 result = forecaster.run_forecast_config(
290     df=df,
291     config=config
292 )
293
294 # Summarizes the CV results
295 cv_results = summarize_grid_search_results(
296     grid_search=result.grid_search,
297     decimals=1,
298     # The below saves space in the printed output. Remove to show all available metrics and columns.
299     cv_report_metrics=None,
300     column_order=["rank", "mean_test", "split_test", "mean_train", "split_train", "mean_fit_time", "mean_score_time", "params"])
301 cv_results["params"] = cv_results["params"].astype(str)
302 cv_results.set_index("params", drop=True, inplace=True)
303 cv_results

Out:

Fitting 3 folds for each of 4 candidates, totalling 12 fits
rank_test_MAPE mean_test_MAPE split_test_MAPE mean_train_MAPE split_train_MAPE mean_fit_time mean_score_time
params
[('estimator__yearly_seasonality', 10), ('estimator__fit_algorithm_dict', {'fit_algorithm': 'linear'}), ('estimator__changepoints_dict', None)] 1 7.3 (5.1, 8.5, 8.3) 4.3 (4.0, 4.3, 4.5) 2.9 1.1
[('estimator__yearly_seasonality', 20), ('estimator__fit_algorithm_dict', {'fit_algorithm': 'linear'}), ('estimator__changepoints_dict', None)] 2 7.3 (5.1, 8.5, 8.3) 4.2 (3.9, 4.2, 4.5) 3.4 1.2
[('estimator__yearly_seasonality', 10), ('estimator__fit_algorithm_dict', {'fit_algorithm': 'ridge'}), ('estimator__changepoints_dict', {'method': 'auto'})] 4 8.3 (5.0, 6.7, 13.2) 4.0 (3.9, 4.2, 4.0) 11.3 1.2
[('estimator__yearly_seasonality', 20), ('estimator__fit_algorithm_dict', {'fit_algorithm': 'ridge'}), ('estimator__changepoints_dict', {'method': 'auto'})] 3 8.2 (5.0, 6.7, 13.0) 4.0 (3.8, 4.1, 4.0) 14.3 1.6


Tip

The simple silverkite templates that use SimpleSilverkiteEstimator are the easiest templates to do grid search, because they support a list of model templates and a list of ModelComponentsParam. For more information, see Template Overview.

Total running time of the script: ( 2 minutes 31.848 seconds)

Download Python source code: 0100_grid_search.py

Download Jupyter notebook: 0100_grid_search.ipynb

Gallery generated by Sphinx-Gallery

Previous Next

© Copyright 2023, LinkedIn.