Backtesting of forecaster model following the folds generated by the TimeSeriesFold
class and using the metric(s) provided.
If forecaster is already trained and initial_train_size is set to None in the
TimeSeriesFold class, no initial train will be done and all data will be used
to evaluate the model. However, the first len(forecaster.last_window) observations
are needed to create the initial predictors, so no predictions are calculated for
them.
A copy of the original forecaster is created so that it is not modified during
the process.
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
Specifies whether probabilistic predictions should be estimated and the
method to use. The following options are supported:
If float, represents the nominal (expected) coverage (between 0 and 1).
For instance, interval=0.95 corresponds to [2.5, 97.5] percentiles.
If list or tuple: Sequence of percentiles to compute, each value must
be between 0 and 100 inclusive. For example, a 95% confidence interval can
be specified as interval = [2.5, 97.5] or multiple percentiles (e.g. 10,
50 and 90) as interval = [10, 50, 90].
If 'bootstrapping' (str): n_boot bootstrapping predictions will be generated.
If scipy.stats distribution object, the distribution parameters will
be estimated for each prediction.
If None, no probabilistic predictions are estimated.
If True, residuals from the training data are used as proxy of
prediction error to create predictions.
If False, out of sample residuals (calibration) are used.
Out-of-sample residuals must be precomputed using Forecaster's
set_out_sample_residuals() method.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Value of predictions. The DataFrame includes the following columns:
fold: Indicates the fold number where the prediction was made.
pred: Predicted values for the corresponding series and time steps.
If interval is not None, additional columns are included depending on the method:
For float: Columns lower_bound and upper_bound.
For list or tuple of 2 elements: Columns lower_bound and upper_bound.
For list or tuple with multiple percentiles: One column per percentile
(e.g., p_10, p_50, p_90).
For 'bootstrapping': One column per bootstrapping iteration
(e.g., pred_boot_0, pred_boot_1, ..., pred_boot_n).
For scipy.stats distribution objects: One column for each estimated
parameter of the distribution (e.g., loc, scale).
If return_predictors is True, one column per predictor is created.
Depending on the relation between steps and fold_stride, the output
may include repeated indexes (if fold_stride < steps) or gaps
(if fold_stride > steps). See Notes below for more details.
Notes
Note on fold_stride vs. steps:
If fold_stride == steps, test sets are placed back-to-back without overlap.
Each observation appears only once in the output DataFrame, so the index is unique.
If fold_stride < steps, test sets overlap. Multiple forecasts are generated
for the same observations and, therefore, the output DataFrame contains repeated
indexes.
If fold_stride > steps, there are gaps between consecutive test sets.
Some observations in the series will not have associated predictions, so
the output DataFrame has non-contiguous indexes.
defbacktesting_forecaster(forecaster:object,y:pd.Series,cv:TimeSeriesFold,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,interval:float|list[float]|tuple[float]|str|object|None=None,interval_method:str='bootstrapping',n_boot:int=250,use_in_sample_residuals:bool=True,use_binned_residuals:bool=True,random_state:int=123,return_predictors:bool=False,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True)->tuple[pd.DataFrame,pd.DataFrame]:""" Backtesting of forecaster model following the folds generated by the TimeSeriesFold class and using the metric(s) provided. If `forecaster` is already trained and `initial_train_size` is set to `None` in the TimeSeriesFold class, no initial train will be done and all data will be used to evaluate the model. However, the first `len(forecaster.last_window)` observations are needed to create the initial predictors, so no predictions are calculated for them. A copy of the original forecaster is created so that it is not modified during the process. Parameters ---------- forecaster : ForecasterRecursive, ForecasterDirect, ForecasterEquivalentDate Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. interval : float, list, tuple, str, object, default None Specifies whether probabilistic predictions should be estimated and the method to use. The following options are supported: - If `float`, represents the nominal (expected) coverage (between 0 and 1). For instance, `interval=0.95` corresponds to `[2.5, 97.5]` percentiles. - If `list` or `tuple`: Sequence of percentiles to compute, each value must be between 0 and 100 inclusive. For example, a 95% confidence interval can be specified as `interval = [2.5, 97.5]` or multiple percentiles (e.g. 10, 50 and 90) as `interval = [10, 50, 90]`. - If 'bootstrapping' (str): `n_boot` bootstrapping predictions will be generated. - If scipy.stats distribution object, the distribution parameters will be estimated for each prediction. - If None, no probabilistic predictions are estimated. interval_method : str, default 'bootstrapping' Technique used to estimate prediction intervals. Available options: - 'bootstrapping': Bootstrapping is used to generate prediction intervals [1]_. - 'conformal': Employs the conformal prediction split method for interval estimation [2]_. n_boot : int, default 250 Number of bootstrapping iterations to perform when estimating prediction intervals. use_in_sample_residuals : bool, default True If `True`, residuals from the training data are used as proxy of prediction error to create predictions. If `False`, out of sample residuals (calibration) are used. Out-of-sample residuals must be precomputed using Forecaster's `set_out_sample_residuals()` method. use_binned_residuals : bool, default True If `True`, residuals are selected based on the predicted values (binned selection). If `False`, residuals are selected randomly. random_state : int, default 123 Seed for the random number generator to ensure reproducibility. return_predictors : bool, default False If `True`, the predictors used to make the predictions are also returned. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds and index of training and validation sets used for backtesting. show_progress : bool, default True Whether to show a progress bar. Returns ------- metric_values : pandas DataFrame Value(s) of the metric(s). backtest_predictions : pandas DataFrame Value of predictions. The DataFrame includes the following columns: - fold: Indicates the fold number where the prediction was made. - pred: Predicted values for the corresponding series and time steps. If `interval` is not `None`, additional columns are included depending on the method: - For `float`: Columns `lower_bound` and `upper_bound`. - For `list` or `tuple` of 2 elements: Columns `lower_bound` and `upper_bound`. - For `list` or `tuple` with multiple percentiles: One column per percentile (e.g., `p_10`, `p_50`, `p_90`). - For `'bootstrapping'`: One column per bootstrapping iteration (e.g., `pred_boot_0`, `pred_boot_1`, ..., `pred_boot_n`). - For `scipy.stats` distribution objects: One column for each estimated parameter of the distribution (e.g., `loc`, `scale`). If `return_predictors` is `True`, one column per predictor is created. Depending on the relation between `steps` and `fold_stride`, the output may include repeated indexes (if `fold_stride < steps`) or gaps (if `fold_stride > steps`). See Notes below for more details. Notes ----- Note on `fold_stride` vs. `steps`: - If `fold_stride == steps`, test sets are placed back-to-back without overlap. Each observation appears only once in the output DataFrame, so the index is unique. - If `fold_stride < steps`, test sets overlap. Multiple forecasts are generated for the same observations and, therefore, the output DataFrame contains repeated indexes. - If `fold_stride > steps`, there are gaps between consecutive test sets. Some observations in the series will not have associated predictions, so the output DataFrame has non-contiguous indexes. References ---------- .. [1] Forecasting: Principles and Practice (3rd ed) Rob J Hyndman and George Athanasopoulos. https://otexts.com/fpp3/prediction-intervals.html .. [2] MAPIE - Model Agnostic Prediction Interval Estimator. https://mapie.readthedocs.io/en/stable/theoretical_description_regression.html#the-split-method """forecaters_allowed=['ForecasterRecursive','ForecasterDirect','ForecasterEquivalentDate','ForecasterRecursiveClassifier']iftype(forecaster).__name__notinforecaters_allowed:raiseTypeError(f"`forecaster` must be of type {forecaters_allowed}, for all other types of "f" forecasters use the functions available in the other `model_selection` "f"modules.")check_backtesting_input(forecaster=forecaster,cv=cv,y=y,metric=metric,interval=interval,interval_method=interval_method,n_boot=n_boot,use_in_sample_residuals=use_in_sample_residuals,use_binned_residuals=use_binned_residuals,random_state=random_state,return_predictors=return_predictors,n_jobs=n_jobs,show_progress=show_progress)metric_values,backtest_predictions=_backtesting_forecaster(forecaster=forecaster,y=y,cv=cv,metric=metric,exog=exog,interval=interval,interval_method=interval_method,n_boot=n_boot,use_in_sample_residuals=use_in_sample_residuals,use_binned_residuals=use_binned_residuals,random_state=random_state,return_predictors=return_predictors,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress)returnmetric_values,backtest_predictions
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
Lists of lags to try, containing int, lists, numpy ndarray, or range
objects. If dict, the keys are used as labels in the results
DataFrame, and the values are used as the lists of lags to try.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column lags: lags configuration for each iteration.
column lags_label: descriptive label or alias for the lags.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defgrid_search_forecaster(forecaster:object,y:pd.Series,cv:TimeSeriesFold|OneStepAheadFold,param_grid:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,lags_grid:(list[int|list[int]|np.ndarray[int]|range[int]]|dict[str,list[int|list[int]|np.ndarray[int]|range[int]]]|None)=None,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" Exhaustive search over specified parameter values for a Forecaster object. Validation is done using time series backtesting. Parameters ---------- forecaster : ForecasterRecursive, ForecasterDirect Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold, OneStepAheadFold TimeSeriesFold or OneStepAheadFold object with the information needed to split the data into folds. **New in version 0.14.0** param_grid : dict Dictionary with parameters names (`str`) as keys and lists of parameter settings to try as values. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. lags_grid : list, dict, default None Lists of lags to try, containing int, lists, numpy ndarray, or range objects. If `dict`, the keys are used as labels in the `results` DataFrame, and the values are used as the lists of lags to try. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column lags: lags configuration for each iteration. - column lags_label: descriptive label or alias for the lags. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. - additional n columns with param = value. """param_grid=list(ParameterGrid(param_grid))results=_evaluate_grid_hyperparameters(forecaster=forecaster,y=y,cv=cv,param_grid=param_grid,metric=metric,exog=exog,lags_grid=lags_grid,return_best=return_best,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,output_file=output_file)returnresults
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
Lists of lags to try, containing int, lists, numpy ndarray, or range
objects. If dict, the keys are used as labels in the results
DataFrame, and the values are used as the lists of lags to try.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column lags: lags configuration for each iteration.
column lags_label: descriptive label or alias for the lags.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defrandom_search_forecaster(forecaster:object,y:pd.Series,cv:TimeSeriesFold|OneStepAheadFold,param_distributions:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,lags_grid:(list[int|list[int]|np.ndarray[int]|range[int]]|dict[str,list[int|list[int]|np.ndarray[int]|range[int]]]|None)=None,n_iter:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" Random search over specified parameter values or distributions for a Forecaster object. Validation is done using time series backtesting. Parameters ---------- forecaster : ForecasterRecursive, ForecasterDirect Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold, OneStepAheadFold TimeSeriesFold or OneStepAheadFold object with the information needed to split the data into folds. **New in version 0.14.0** param_distributions : dict Dictionary with parameters names (`str`) as keys and distributions or lists of parameters to try. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. lags_grid : list, dict, default None Lists of lags to try, containing int, lists, numpy ndarray, or range objects. If `dict`, the keys are used as labels in the `results` DataFrame, and the values are used as the lists of lags to try. n_iter : int, default 10 Number of parameter settings that are sampled per lags configuration. n_iter trades off runtime vs quality of the solution. random_state : int, default 123 Sets a seed to the random sampling for reproducible output. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column lags: lags configuration for each iteration. - column lags_label: descriptive label or alias for the lags. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. - additional n columns with param = value. """param_grid=list(ParameterSampler(param_distributions,n_iter=n_iter,random_state=random_state))results=_evaluate_grid_hyperparameters(forecaster=forecaster,y=y,cv=cv,param_grid=param_grid,metric=metric,exog=exog,lags_grid=lags_grid,return_best=return_best,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,output_file=output_file)returnresults
Function with argument trial which returns a dictionary with parameters names
(str) as keys and Trial object from optuna (trial.suggest_float,
trial.suggest_int, trial.suggest_categorical) as values.
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
Sets a seed to the sampling for reproducible output. When a new sampler
is passed in kwargs_create_study, the seed must be set within the
sampler. For example {'sampler': TPESampler(seed=145)}.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
Additional keyword arguments (key, value mappings) to pass to optuna.create_study().
If default, the direction is set to 'minimize' and a TPESampler(seed=123)
sampler is used during optimization.
defbayesian_search_forecaster(forecaster:object,y:pd.Series,cv:TimeSeriesFold|OneStepAheadFold,search_space:Callable,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,n_trials:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,output_file:str|None=None,kwargs_create_study:dict={},kwargs_study_optimize:dict={})->tuple[pd.DataFrame,object]:""" Bayesian search for hyperparameters of a Forecaster object. Parameters ---------- forecaster : ForecasterRecursive, ForecasterDirect Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold, OneStepAheadFold TimeSeriesFold or OneStepAheadFold object with the information needed to split the data into folds. **New in version 0.14.0** search_space : Callable (optuna) Function with argument `trial` which returns a dictionary with parameters names (`str`) as keys and Trial object from optuna (trial.suggest_float, trial.suggest_int, trial.suggest_categorical) as values. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. n_trials : int, default 10 Number of parameter settings that are sampled in each lag configuration. random_state : int, default 123 Sets a seed to the sampling for reproducible output. When a new sampler is passed in `kwargs_create_study`, the seed must be set within the sampler. For example `{'sampler': TPESampler(seed=145)}`. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. kwargs_create_study : dict, default {} Additional keyword arguments (key, value mappings) to pass to optuna.create_study(). If default, the direction is set to 'minimize' and a TPESampler(seed=123) sampler is used during optimization. kwargs_study_optimize : dict, default {} Additional keyword arguments (key, value mappings) to pass to study.optimize(). Returns ------- results : pandas DataFrame Results for each combination of parameters. - column lags: lags configuration for each iteration. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. - additional n columns with param = value. best_trial : optuna object The best optimization result returned as a FrozenTrial optuna object. """ifreturn_bestandexogisnotNoneand(len(exog)!=len(y)):raiseValueError(f"`exog` must have same number of samples as `y`. "f"length `exog`: ({len(exog)}), length `y`: ({len(y)})")results,best_trial=_bayesian_search_optuna(forecaster=forecaster,y=y,cv=cv,exog=exog,search_space=search_space,metric=metric,n_trials=n_trials,random_state=random_state,return_best=return_best,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,output_file=output_file,kwargs_create_study=kwargs_create_study,kwargs_study_optimize=kwargs_study_optimize)returnresults,best_trial
Backtesting of forecaster model following the folds generated by the TimeSeriesFold
class and using the metric(s) provided.
If forecaster is already trained and initial_train_size is set to None in the
TimeSeriesFold class, no initial train will be done and all data will be used
to evaluate the model. However, the first len(forecaster.last_window) observations
are needed to create the initial predictors, so no predictions are calculated for
them.
A copy of the original forecaster is created so that it is not modified during
the process.
Specifies whether probabilistic predictions should be estimated and the
method to use. The following options are supported:
If float, represents the nominal (expected) coverage (between 0 and 1).
For instance, interval=0.95 corresponds to [2.5, 97.5] percentiles.
If list or tuple: Sequence of percentiles to compute, each value must
be between 0 and 100 inclusive. For example, a 95% confidence interval can
be specified as interval = [2.5, 97.5] or multiple percentiles (e.g. 10,
50 and 90) as interval = [10, 50, 90].
If 'bootstrapping' (str): n_boot bootstrapping predictions will be generated.
If scipy.stats distribution object, the distribution parameters will
be estimated for each prediction.
If None, no probabilistic predictions are estimated.
If True, residuals from the training data are used as proxy of
prediction error to create predictions.
If False, out of sample residuals (calibration) are used.
Out-of-sample residuals must be precomputed using Forecaster's
set_out_sample_residuals() method.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
If True, skforecast warnings will be suppressed during the backtesting
process. See skforecast.exceptions.warn_skforecast_categories for more
information.
False
Returns:
Name
Type
Description
metrics_levels
pandas DataFrame
Value(s) of the metric(s). Index are the levels and columns the metrics.
backtest_predictions
pandas DataFrame
Long-format DataFrame containing the predicted values for each series. The
DataFrame includes the following columns:
level: Identifier for the time series or level being predicted.
fold: Indicates the fold number where the prediction was made.
pred: Predicted values for the corresponding series and time steps.
If interval is not None, additional columns are included depending on the method:
For float: Columns lower_bound and upper_bound.
For list or tuple of 2 elements: Columns lower_bound and upper_bound.
For list or tuple with multiple percentiles: One column per percentile
(e.g., p_10, p_50, p_90).
For 'bootstrapping': One column per bootstrapping iteration
(e.g., pred_boot_0, pred_boot_1, ..., pred_boot_n).
For scipy.stats distribution objects: One column for each estimated
parameter of the distribution (e.g., loc, scale).
If return_predictors is True, one column per predictor is created.
Depending on the relation between steps and fold_stride, the output
may include repeated indexes (if fold_stride < steps) or gaps
(if fold_stride > steps). See Notes below for more details.
Notes
Note on fold_stride vs. steps:
If fold_stride == steps, test sets are placed back-to-back without overlap.
Each observation appears only once in the output DataFrame, so the index is unique.
If fold_stride < steps, test sets overlap. Multiple forecasts are generated
for the same observations and, therefore, the output DataFrame contains repeated
indexes.
If fold_stride > steps, there are gaps between consecutive test sets.
Some observations in the series will not have associated predictions, so
the output DataFrame has non-contiguous indexes.
defbacktesting_forecaster_multiseries(forecaster:object,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame],cv:TimeSeriesFold,metric:str|Callable|list[str|Callable],levels:str|list[str]|None=None,add_aggregated_metric:bool=True,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,interval:float|list[float]|tuple[float]|str|object|None=None,interval_method:str='conformal',n_boot:int=250,use_in_sample_residuals:bool=True,use_binned_residuals:bool=True,random_state:int=123,return_predictors:bool=False,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,suppress_warnings:bool=False)->tuple[pd.DataFrame,pd.DataFrame]:""" Backtesting of forecaster model following the folds generated by the TimeSeriesFold class and using the metric(s) provided. If `forecaster` is already trained and `initial_train_size` is set to `None` in the TimeSeriesFold class, no initial train will be done and all data will be used to evaluate the model. However, the first `len(forecaster.last_window)` observations are needed to create the initial predictors, so no predictions are calculated for them. A copy of the original forecaster is created so that it is not modified during the process. Parameters ---------- forecaster : ForecasterRecursiveMultiSeries, ForecasterDirectMultiVariate, ForecasterRnn Forecaster model. series : pandas DataFrame, dict Training time series. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. levels : str, list, default None Time series to be predicted. If `None` all levels will be predicted. add_aggregated_metric : bool, default True If `True`, and multiple series (`levels`) are predicted, the aggregated metrics (average, weighted average and pooled) are also returned. - 'average': the average (arithmetic mean) of all levels. - 'weighted_average': the average of the metrics weighted by the number of predicted values of each level. - 'pooling': the values of all levels are pooled and then the metric is calculated. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. interval : float, list, tuple, str, object, default None Specifies whether probabilistic predictions should be estimated and the method to use. The following options are supported: - If `float`, represents the nominal (expected) coverage (between 0 and 1). For instance, `interval=0.95` corresponds to `[2.5, 97.5]` percentiles. - If `list` or `tuple`: Sequence of percentiles to compute, each value must be between 0 and 100 inclusive. For example, a 95% confidence interval can be specified as `interval = [2.5, 97.5]` or multiple percentiles (e.g. 10, 50 and 90) as `interval = [10, 50, 90]`. - If 'bootstrapping' (str): `n_boot` bootstrapping predictions will be generated. - If scipy.stats distribution object, the distribution parameters will be estimated for each prediction. - If None, no probabilistic predictions are estimated. interval_method : str, default 'conformal' Technique used to estimate prediction intervals. Available options: - 'bootstrapping': Bootstrapping is used to generate prediction intervals [1]_. - 'conformal': Employs the conformal prediction split method for interval estimation [2]_. n_boot : int, default 250 Number of bootstrapping iterations to perform when estimating prediction intervals. use_in_sample_residuals : bool, default True If `True`, residuals from the training data are used as proxy of prediction error to create predictions. If `False`, out of sample residuals (calibration) are used. Out-of-sample residuals must be precomputed using Forecaster's `set_out_sample_residuals()` method. use_binned_residuals : bool, default True If `True`, residuals are selected based on the predicted values (binned selection). If `False`, residuals are selected randomly. random_state : int, default 123 Seed for the random number generator to ensure reproducibility. return_predictors : bool, default False If `True`, the predictors used to make the predictions are also returned. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds and index of training and validation sets used for backtesting. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the backtesting process. See skforecast.exceptions.warn_skforecast_categories for more information. Returns ------- metrics_levels : pandas DataFrame Value(s) of the metric(s). Index are the levels and columns the metrics. backtest_predictions : pandas DataFrame Long-format DataFrame containing the predicted values for each series. The DataFrame includes the following columns: - `level`: Identifier for the time series or level being predicted. - fold: Indicates the fold number where the prediction was made. - `pred`: Predicted values for the corresponding series and time steps. If `interval` is not `None`, additional columns are included depending on the method: - For `float`: Columns `lower_bound` and `upper_bound`. - For `list` or `tuple` of 2 elements: Columns `lower_bound` and `upper_bound`. - For `list` or `tuple` with multiple percentiles: One column per percentile (e.g., `p_10`, `p_50`, `p_90`). - For `'bootstrapping'`: One column per bootstrapping iteration (e.g., `pred_boot_0`, `pred_boot_1`, ..., `pred_boot_n`). - For `scipy.stats` distribution objects: One column for each estimated parameter of the distribution (e.g., `loc`, `scale`). If `return_predictors` is `True`, one column per predictor is created. Depending on the relation between `steps` and `fold_stride`, the output may include repeated indexes (if `fold_stride < steps`) or gaps (if `fold_stride > steps`). See Notes below for more details. Notes ----- Note on `fold_stride` vs. `steps`: - If `fold_stride == steps`, test sets are placed back-to-back without overlap. Each observation appears only once in the output DataFrame, so the index is unique. - If `fold_stride < steps`, test sets overlap. Multiple forecasts are generated for the same observations and, therefore, the output DataFrame contains repeated indexes. - If `fold_stride > steps`, there are gaps between consecutive test sets. Some observations in the series will not have associated predictions, so the output DataFrame has non-contiguous indexes. References ---------- .. [1] Forecasting: Principles and Practice (3rd ed) Rob J Hyndman and George Athanasopoulos. https://otexts.com/fpp3/prediction-intervals.html .. [2] MAPIE - Model Agnostic Prediction Interval Estimator. https://mapie.readthedocs.io/en/stable/theoretical_description_regression.html#the-split-method """multi_series_forecasters=['ForecasterRecursiveMultiSeries','ForecasterDirectMultiVariate','ForecasterRnn']forecaster_name=type(forecaster).__name__ifforecaster_namenotinmulti_series_forecasters:raiseTypeError(f"`forecaster` must be of type {multi_series_forecasters}, "f"for all other types of forecasters use the functions available in "f"the `model_selection` module. Got {forecaster_name}")set_skforecast_warnings(suppress_warnings,action='ignore')ifforecaster_name=='ForecasterRecursiveMultiSeries':series,series_indexes=check_preprocess_series(series)ifexogisnotNone:series_names_in_=list(series.keys())exog_dict={serie:Noneforserieinseries_names_in_}exog,_=check_preprocess_exog_multiseries(series_names_in_=series_names_in_,series_index_type=type(series_indexes[series_names_in_[0]]),exog=exog,exog_dict=exog_dict)set_skforecast_warnings(suppress_warnings,action='default')check_backtesting_input(forecaster=forecaster,cv=cv,metric=metric,add_aggregated_metric=add_aggregated_metric,series=series,exog=exog,interval=interval,interval_method=interval_method,n_boot=n_boot,use_in_sample_residuals=use_in_sample_residuals,use_binned_residuals=use_binned_residuals,random_state=random_state,return_predictors=return_predictors,n_jobs=n_jobs,show_progress=show_progress,suppress_warnings=suppress_warnings)metrics_levels,backtest_predictions=_backtesting_forecaster_multiseries(forecaster=forecaster,series=series,cv=cv,levels=levels,metric=metric,add_aggregated_metric=add_aggregated_metric,exog=exog,interval=interval,interval_method=interval_method,n_boot=n_boot,use_in_sample_residuals=use_in_sample_residuals,use_binned_residuals=use_binned_residuals,random_state=random_state,return_predictors=return_predictors,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,suppress_warnings=suppress_warnings)returnmetrics_levels,backtest_predictions
Aggregation method/s used to combine the metric/s of all levels (series)
when multiple levels are predicted. If list, the first aggregation method
is used to select the best parameters.
'average': the average (arithmetic mean) of all levels.
'weighted_average': the average of the metrics weighted by the number of
predicted values of each level.
'pooling': the values of all levels are pooled and then the metric is
calculated.
Lists of lags to try, containing int, lists, numpy ndarray, or range
objects. If dict, the keys are used as labels in the results
DataFrame, and the values are used as the lists of lags to try.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
If True, skforecast warnings will be suppressed during the hyperparameter
search. See skforecast.exceptions.warn_skforecast_categories for more
information.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column levels: levels configuration for each iteration.
column lags: lags configuration for each iteration.
column lags_label: descriptive label or alias for the lags.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration. The resulting
metric will be the average of the optimization of all levels.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defgrid_search_forecaster_multiseries(forecaster:object,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame],cv:TimeSeriesFold|OneStepAheadFold,param_grid:dict,metric:str|Callable|list[str|Callable],aggregate_metric:str|list[str]=['weighted_average','average','pooling'],levels:str|list[str]|None=None,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,lags_grid:(list[int|list[int]|np.ndarray[int]|range[int]]|dict[str,list[int|list[int]|np.ndarray[int]|range[int]]]|None)=None,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,suppress_warnings:bool=False,output_file:str|None=None)->pd.DataFrame:""" Exhaustive search over specified parameter values for a Forecaster object. Validation is done using multi-series backtesting. Parameters ---------- forecaster : ForecasterRecursiveMultiSeries, ForecasterDirectMultiVariate Forecaster model. series : pandas DataFrame, dict Training time series. cv : TimeSeriesFold, OneStepAheadFold TimeSeriesFold or OneStepAheadFold object with the information needed to split the data into folds. **New in version 0.14.0** param_grid : dict Dictionary with parameters names (`str`) as keys and lists of parameter settings to try as values. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. aggregate_metric : str, list, default `['weighted_average', 'average', 'pooling']` Aggregation method/s used to combine the metric/s of all levels (series) when multiple levels are predicted. If list, the first aggregation method is used to select the best parameters. - 'average': the average (arithmetic mean) of all levels. - 'weighted_average': the average of the metrics weighted by the number of predicted values of each level. - 'pooling': the values of all levels are pooled and then the metric is calculated. levels : str, list, default None level (`str`) or levels (`list`) at which the forecaster is optimized. If `None`, all levels are taken into account. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. lags_grid : list, dict, default None Lists of lags to try, containing int, lists, numpy ndarray, or range objects. If `dict`, the keys are used as labels in the `results` DataFrame, and the values are used as the lists of lags to try. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the hyperparameter search. See skforecast.exceptions.warn_skforecast_categories for more information. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column levels: levels configuration for each iteration. - column lags: lags configuration for each iteration. - column lags_label: descriptive label or alias for the lags. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. The resulting metric will be the average of the optimization of all levels. - additional n columns with param = value. """param_grid=list(ParameterGrid(param_grid))results=_evaluate_grid_hyperparameters_multiseries(forecaster=forecaster,series=series,cv=cv,param_grid=param_grid,metric=metric,aggregate_metric=aggregate_metric,levels=levels,exog=exog,lags_grid=lags_grid,n_jobs=n_jobs,return_best=return_best,verbose=verbose,show_progress=show_progress,suppress_warnings=suppress_warnings,output_file=output_file)returnresults
Aggregation method/s used to combine the metric/s of all levels (series)
when multiple levels are predicted. If list, the first aggregation method
is used to select the best parameters.
'average': the average (arithmetic mean) of all levels.
'weighted_average': the average of the metrics weighted by the number of
predicted values of each level.
'pooling': the values of all levels are pooled and then the metric is
calculated.
Lists of lags to try, containing int, lists, numpy ndarray, or range
objects. If dict, the keys are used as labels in the results
DataFrame, and the values are used as the lists of lags to try.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
If True, skforecast warnings will be suppressed during the hyperparameter
search. See skforecast.exceptions.warn_skforecast_categories for more
information.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column levels: levels configuration for each iteration.
column lags: lags configuration for each iteration.
column lags_label: descriptive label or alias for the lags.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration. The resulting
metric will be the average of the optimization of all levels.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defrandom_search_forecaster_multiseries(forecaster:object,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame],cv:TimeSeriesFold|OneStepAheadFold,param_distributions:dict,metric:str|Callable|list[str|Callable],aggregate_metric:str|list[str]=['weighted_average','average','pooling'],levels:str|list[str]|None=None,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,lags_grid:(list[int|list[int]|np.ndarray[int]|range[int]]|dict[str,list[int|list[int]|np.ndarray[int]|range[int]]]|None)=None,n_iter:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,suppress_warnings:bool=False,output_file:str|None=None)->pd.DataFrame:""" Random search over specified parameter values or distributions for a Forecaster object. Validation is done using multi-series backtesting. Parameters ---------- forecaster : ForecasterRecursiveMultiSeries, ForecasterDirectMultiVariate Forecaster model. series : pandas DataFrame, dict Training time series. cv : TimeSeriesFold, OneStepAheadFold TimeSeriesFold or OneStepAheadFold object with the information needed to split the data into folds. param_distributions : dict Dictionary with parameters names (`str`) as keys and distributions or lists of parameters to try. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. aggregate_metric : str, list, default `['weighted_average', 'average', 'pooling']` Aggregation method/s used to combine the metric/s of all levels (series) when multiple levels are predicted. If list, the first aggregation method is used to select the best parameters. - 'average': the average (arithmetic mean) of all levels. - 'weighted_average': the average of the metrics weighted by the number of predicted values of each level. - 'pooling': the values of all levels are pooled and then the metric is calculated. levels : str, list, default None level (`str`) or levels (`list`) at which the forecaster is optimized. If `None`, all levels are taken into account. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. lags_grid : list, dict, default None Lists of lags to try, containing int, lists, numpy ndarray, or range objects. If `dict`, the keys are used as labels in the `results` DataFrame, and the values are used as the lists of lags to try. n_iter : int, default 10 Number of parameter settings that are sampled per lags configuration. n_iter trades off runtime vs quality of the solution. random_state : int, default 123 Sets a seed to the random sampling for reproducible output. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the hyperparameter search. See skforecast.exceptions.warn_skforecast_categories for more information. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column levels: levels configuration for each iteration. - column lags: lags configuration for each iteration. - column lags_label: descriptive label or alias for the lags. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. The resulting metric will be the average of the optimization of all levels. - additional n columns with param = value. """param_grid=list(ParameterSampler(param_distributions,n_iter=n_iter,random_state=random_state))results=_evaluate_grid_hyperparameters_multiseries(forecaster=forecaster,series=series,cv=cv,param_grid=param_grid,metric=metric,aggregate_metric=aggregate_metric,levels=levels,exog=exog,lags_grid=lags_grid,return_best=return_best,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,suppress_warnings=suppress_warnings,output_file=output_file)returnresults
Function with argument trial which returns a dictionary with parameters names
(str) as keys and Trial object from optuna (trial.suggest_float,
trial.suggest_int, trial.suggest_categorical) as values.
Aggregation method/s used to combine the metric/s of all levels (series)
when multiple levels are predicted. If list, the first aggregation method
is used to select the best parameters.
'average': the average (arithmetic mean) of all levels.
'weighted_average': the average of the metrics weighted by the number of
predicted values of each level.
'pooling': the values of all levels are pooled and then the metric is
calculated.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
If True, skforecast warnings will be suppressed during the hyperparameter
search. See skforecast.exceptions.warn_skforecast_categories for more
information.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
Additional keyword arguments (key, value mappings) to pass to optuna.create_study().
If default, the direction is set to 'minimize' and a TPESampler(seed=123)
sampler is used during optimization.
defbayesian_search_forecaster_multiseries(forecaster:object,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame],cv:TimeSeriesFold|OneStepAheadFold,search_space:Callable,metric:str|Callable|list[str|Callable],aggregate_metric:str|list[str]=['weighted_average','average','pooling'],levels:str|list[str]|None=None,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,n_trials:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,show_progress:bool=True,suppress_warnings:bool=False,output_file:str|None=None,kwargs_create_study:dict={},kwargs_study_optimize:dict={})->tuple[pd.DataFrame,object]:""" Bayesian search for hyperparameters of a Forecaster object using optuna library. Parameters ---------- forecaster : ForecasterRecursiveMultiSeries, ForecasterDirectMultiVariate Forecaster model. series : pandas DataFrame, dict Training time series. search_space : Callable Function with argument `trial` which returns a dictionary with parameters names (`str`) as keys and Trial object from optuna (trial.suggest_float, trial.suggest_int, trial.suggest_categorical) as values. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. aggregate_metric : str, list, default `['weighted_average', 'average', 'pooling']` Aggregation method/s used to combine the metric/s of all levels (series) when multiple levels are predicted. If list, the first aggregation method is used to select the best parameters. - 'average': the average (arithmetic mean) of all levels. - 'weighted_average': the average of the metrics weighted by the number of predicted values of each level. - 'pooling': the values of all levels are pooled and then the metric is calculated. levels : str, list, default None level (`str`) or levels (`list`) at which the forecaster is optimized. If `None`, all levels are taken into account. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. n_trials : int, default 10 Number of parameter settings that are sampled in each lag configuration. random_state : int, default 123 Sets a seed to the sampling for reproducible output. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the hyperparameter search. See skforecast.exceptions.warn_skforecast_categories for more information. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. kwargs_create_study : dict, default {} Additional keyword arguments (key, value mappings) to pass to optuna.create_study(). If default, the direction is set to 'minimize' and a TPESampler(seed=123) sampler is used during optimization. kwargs_study_optimize : dict, default {} Additional keyword arguments (key, value mappings) to pass to study.optimize(). Returns ------- results : pandas DataFrame Results for each combination of parameters. - column levels: levels configuration for each iteration. - column lags: lags configuration for each iteration. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. The resulting metric will be the average of the optimization of all levels. - additional n columns with param = value. best_trial : optuna object The best optimization result returned as a FrozenTrial optuna object. """results,best_trial=_bayesian_search_optuna_multiseries(forecaster=forecaster,series=series,cv=cv,exog=exog,levels=levels,search_space=search_space,metric=metric,aggregate_metric=aggregate_metric,n_trials=n_trials,random_state=random_state,return_best=return_best,n_jobs=n_jobs,verbose=verbose,show_progress=show_progress,suppress_warnings=suppress_warnings,output_file=output_file,kwargs_create_study=kwargs_create_study,kwargs_study_optimize=kwargs_study_optimize)returnresults,best_trial
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
Confidence of the prediction interval estimated. The values must be
symmetric. Sequence of percentiles to compute, which must be between
0 and 100 inclusive. For example, interval of 95% should be as
interval = [2.5, 97.5]. If both, alpha and interval are
provided, alpha will be used.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Value of predictions. The DataFrame includes the following columns:
fold: Indicates the fold number where the prediction was made.
pred: Predicted values for the corresponding series and time steps.
If interval is not None, additional columns are included:
lower_bound: lower bound of the interval.
upper_bound: upper bound of the interval.
Depending on the relation between steps and fold_stride, the output
may include repeated indexes (if fold_stride < steps) or gaps
(if fold_stride > steps). See Notes below for more details.
Notes
Note on fold_stride vs. steps:
If fold_stride == steps, test sets are placed back-to-back without overlap.
Each observation appears only once in the output DataFrame, so the index is unique.
If fold_stride < steps, test sets overlap. Multiple forecasts are generated
for the same observations and, therefore, the output DataFrame contains repeated
indexes.
If fold_stride > steps, there are gaps between consecutive test sets.
Some observations in the series will not have associated predictions, so
the output DataFrame has non-contiguous indexes.
Source code in skforecast\model_selection\_validation.py
defbacktesting_stats(forecaster:object,y:pd.Series,cv:TimeSeriesFold,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,alpha:float|None=None,interval:list[float]|tuple[float]|None=None,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True)->tuple[pd.DataFrame,pd.DataFrame]:""" Backtesting of ForecasterStats. A copy of the original forecaster is created so that it is not modified during the process. Parameters ---------- forecaster : ForecasterStats Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. alpha : float, default 0.05 The confidence intervals for the forecasts are (1 - alpha) %. If both, `alpha` and `interval` are provided, `alpha` will be used. interval : list, tuple, default None Confidence of the prediction interval estimated. The values must be symmetric. Sequence of percentiles to compute, which must be between 0 and 100 inclusive. For example, interval of 95% should be as `interval = [2.5, 97.5]`. If both, `alpha` and `interval` are provided, `alpha` will be used. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds and index of training and validation sets used for backtesting. suppress_warnings_fit : bool, default False If `True`, warnings generated during fitting will be ignored. show_progress : bool, default True Whether to show a progress bar. Returns ------- metric_values : pandas DataFrame Value(s) of the metric(s). backtest_predictions : pandas DataFrame Value of predictions. The DataFrame includes the following columns: - fold: Indicates the fold number where the prediction was made. - pred: Predicted values for the corresponding series and time steps. If `interval` is not `None`, additional columns are included: - lower_bound: lower bound of the interval. - upper_bound: upper bound of the interval. Depending on the relation between `steps` and `fold_stride`, the output may include repeated indexes (if `fold_stride < steps`) or gaps (if `fold_stride > steps`). See Notes below for more details. Notes ----- Note on `fold_stride` vs. `steps`: - If `fold_stride == steps`, test sets are placed back-to-back without overlap. Each observation appears only once in the output DataFrame, so the index is unique. - If `fold_stride < steps`, test sets overlap. Multiple forecasts are generated for the same observations and, therefore, the output DataFrame contains repeated indexes. - If `fold_stride > steps`, there are gaps between consecutive test sets. Some observations in the series will not have associated predictions, so the output DataFrame has non-contiguous indexes. """iftype(forecaster).__name__notin['ForecasterStats']:raiseTypeError("`forecaster` must be of type `ForecasterStats`, for all other ""types of forecasters use the functions available in the other ""`model_selection` modules.")check_backtesting_input(forecaster=forecaster,cv=cv,y=y,metric=metric,interval=interval,alpha=alpha,n_jobs=n_jobs,show_progress=show_progress,suppress_warnings_fit=suppress_warnings_fit)metric_values,backtest_predictions=_backtesting_stats(forecaster=forecaster,y=y,cv=cv,metric=metric,exog=exog,alpha=alpha,interval=interval,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress)returnmetric_values,backtest_predictions
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defgrid_search_stats(forecaster:object,y:pd.Series,cv:TimeSeriesFold,param_grid:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" Exhaustive search over specified parameter values for a ForecasterStats object. Validation is done using time series backtesting. Parameters ---------- forecaster : ForecasterStats Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. **New in version 0.14.0** param_grid : dict Dictionary with parameters names (`str`) as keys and lists of parameter settings to try as values. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. suppress_warnings_fit : bool, default False If `True`, warnings generated during fitting will be ignored. show_progress : bool, default True Whether to show a progress bar. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. - additional n columns with param = value. """param_grid=list(ParameterGrid(param_grid))results=_evaluate_grid_hyperparameters_stats(forecaster=forecaster,y=y,cv=cv,param_grid=param_grid,metric=metric,exog=exog,return_best=return_best,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress,output_file=output_file)returnresults
Metric used to quantify the goodness of fit of the model.
If string: {'mean_squared_error', 'mean_absolute_error',
'mean_absolute_percentage_error', 'mean_squared_log_error',
'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'}
If Callable: Function with arguments y_true, y_pred and y_train
(Optional) that returns a float.
If list: List containing multiple strings and/or Callables.
required
exog
pandas Series, pandas DataFrame
Exogenous variable/s included as predictor/s. Must have the same
number of observations as y and should be aligned so that y[i] is
regressed on exog[i].
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_backtesting.
Specifies the filename or full path where the results should be saved.
The results will be saved in a tab-separated values (TSV) format. If
None, the results will not be saved to a file.
None
Returns:
Name
Type
Description
results
pandas DataFrame
Results for each combination of parameters.
column params: parameters configuration for each iteration.
column metric: metric value estimated for each iteration.
additional n columns with param = value.
Source code in skforecast\model_selection\_search.py
defrandom_search_stats(forecaster:object,y:pd.Series,cv:TimeSeriesFold,param_distributions:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,n_iter:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" Random search over specified parameter values or distributions for a ForecasterStats object. Validation is done using time series backtesting. Parameters ---------- forecaster : ForecasterStats Forecaster model. y : pandas Series Training time series. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. **New in version 0.14.0** param_distributions : dict Dictionary with parameters names (`str`) as keys and distributions or lists of parameters to try. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. - If `string`: {'mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'mean_squared_log_error', 'mean_absolute_scaled_error', 'root_mean_squared_scaled_error'} - If `Callable`: Function with arguments `y_true`, `y_pred` and `y_train` (Optional) that returns a float. - If `list`: List containing multiple strings and/or Callables. exog : pandas Series, pandas DataFrame, default None Exogenous variable/s included as predictor/s. Must have the same number of observations as `y` and should be aligned so that y[i] is regressed on exog[i]. n_iter : int, default 10 Number of parameter settings that are sampled. n_iter trades off runtime vs quality of the solution. random_state : int, default 123 Sets a seed to the random sampling for reproducible output. return_best : bool, default True Refit the `forecaster` using the best found parameters on the whole data. n_jobs : int, 'auto', default 'auto' The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_backtesting. verbose : bool, default False Print number of folds used for cv or backtesting. suppress_warnings_fit : bool, default False If `True`, warnings generated during fitting will be ignored. show_progress : bool, default True Whether to show a progress bar. output_file : str, default None Specifies the filename or full path where the results should be saved. The results will be saved in a tab-separated values (TSV) format. If `None`, the results will not be saved to a file. Returns ------- results : pandas DataFrame Results for each combination of parameters. - column params: parameters configuration for each iteration. - column metric: metric value estimated for each iteration. - additional n columns with param = value. """param_grid=list(ParameterSampler(param_distributions,n_iter=n_iter,random_state=random_state))results=_evaluate_grid_hyperparameters_stats(forecaster=forecaster,y=y,cv=cv,param_grid=param_grid,metric=metric,exog=exog,return_best=return_best,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress,output_file=output_file)returnresults
@runtime_deprecated(replacement="backtesting_stats",version="0.19.0",removal="0.20.0")@deprecated("`backtesting_sarimax` is deprecated since version 0.19.0; use `backtesting_stats` instead. It will be removed in version 0.20.0.")defbacktesting_sarimax(forecaster:object,y:pd.Series,cv:TimeSeriesFold,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,alpha:float|None=None,interval:list[float]|tuple[float]|None=None,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True)->tuple[pd.DataFrame,pd.DataFrame]:""" !!! warning "Deprecated" This function is deprecated since skforecast 0.19. Please use `backtesting_stats` instead. """returnbacktesting_stats(forecaster=forecaster,y=y,cv=cv,metric=metric,exog=exog,alpha=alpha,interval=interval,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress)
@runtime_deprecated(replacement="grid_search_stats",version="0.19.0",removal="0.20.0")@deprecated("`grid_search_sarimax` is deprecated since version 0.19.0; use `grid_search_stats` instead. It will be removed in version 0.20.0.")defgrid_search_sarimax(forecaster:object,y:pd.Series,cv:TimeSeriesFold,param_grid:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" !!! warning "Deprecated" This function is deprecated since skforecast 0.19. Please use `grid_search_stats` instead. """returngrid_search_stats(forecaster=forecaster,y=y,cv=cv,param_grid=param_grid,metric=metric,exog=exog,return_best=return_best,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress,output_file=output_file)
@runtime_deprecated(replacement="random_search_stats",version="0.19.0",removal="0.20.0")@deprecated("`random_search_sarimax` is deprecated since version 0.19.0; use `random_search_stats` instead. It will be removed in version 0.20.0.")defrandom_search_sarimax(forecaster:object,y:pd.Series,cv:TimeSeriesFold,param_distributions:dict,metric:str|Callable|list[str|Callable],exog:pd.Series|pd.DataFrame|None=None,n_iter:int=10,random_state:int=123,return_best:bool=True,n_jobs:int|str='auto',verbose:bool=False,suppress_warnings_fit:bool=False,show_progress:bool=True,output_file:str|None=None)->pd.DataFrame:""" !!! warning "Deprecated" This function is deprecated since skforecast 0.19. Please use `random_search_stats` instead. """returnrandom_search_stats(forecaster=forecaster,y=y,cv=cv,param_distributions=param_distributions,metric=metric,exog=exog,n_iter=n_iter,random_state=random_state,return_best=return_best,n_jobs=n_jobs,verbose=verbose,suppress_warnings_fit=suppress_warnings_fit,show_progress=show_progress,output_file=output_file)
Base class for all Fold classes in skforecast. All fold classes should specify
all the parameters that can be set at the class level in their __init__.
For example, if skip_folds=3 and there are 10 folds, the returned folds are
0, 3, 6, and 9. If skip_folds=[1, 2, 3], the returned folds are 0, 4, 5, 6, 7,
8, and 9.
def_validate_params(self,cv_name:str,steps:int|None=None,initial_train_size:int|str|pd.Timestamp|None=None,fold_stride:int|None=None,window_size:int|None=None,differentiation:int|None=None,refit:bool|int=False,fixed_train_size:bool=True,gap:int=0,skip_folds:int|list[int]|None=None,allow_incomplete_fold:bool=True,return_all_indexes:bool=False,verbose:bool=True,**kwargs)->None:""" Validate all input parameters to ensure correctness. """ifcv_name=="TimeSeriesFold":ifnotisinstance(steps,(int,np.integer))orsteps<1:raiseValueError(f"`steps` must be an integer greater than 0. Got {steps}.")ifnotisinstance(initial_train_size,(int,np.integer,str,pd.Timestamp,type(None))):raiseValueError(f"`initial_train_size` must be an integer greater than 0, a date "f"string, a pandas Timestamp, or None. Got {initial_train_size}.")ifisinstance(initial_train_size,(int,np.integer))andinitial_train_size<1:raiseValueError(f"`initial_train_size` must be an integer greater than 0, "f"a date string, a pandas Timestamp, or None. Got {initial_train_size}.")iffold_strideisnotNone:ifnotisinstance(fold_stride,(int,np.integer))orfold_stride<1:raiseValueError(f"`fold_stride` must be an integer greater than 0. Got {fold_stride}.")ifnotisinstance(refit,(bool,int,np.integer)):raiseTypeError(f"`refit` must be a boolean or an integer equal or greater than 0. "f"Got {refit}.")ifisinstance(refit,(int,np.integer))andnotisinstance(refit,bool)andrefit<0:raiseTypeError(f"`refit` must be a boolean or an integer equal or greater than 0. "f"Got {refit}.")ifnotisinstance(fixed_train_size,bool):raiseTypeError(f"`fixed_train_size` must be a boolean: `True`, `False`. "f"Got {fixed_train_size}.")ifnotisinstance(gap,(int,np.integer))orgap<0:raiseValueError(f"`gap` must be an integer greater than or equal to 0. Got {gap}.")ifskip_foldsisnotNone:ifnotisinstance(skip_folds,(int,np.integer,list,type(None))):raiseTypeError(f"`skip_folds` must be an integer greater than 0, a list of "f"integers or `None`. Got {skip_folds}.")ifisinstance(skip_folds,(int,np.integer))andskip_folds<1:raiseValueError(f"`skip_folds` must be an integer greater than 0, a list of "f"integers or `None`. Got {skip_folds}.")ifisinstance(skip_folds,list)andany([x<1forxinskip_folds]):raiseValueError(f"`skip_folds` list must contain integers greater than or "f"equal to 1. The first fold is always needed to train the "f"forecaster. Got {skip_folds}.")ifnotisinstance(allow_incomplete_fold,bool):raiseTypeError(f"`allow_incomplete_fold` must be a boolean: `True`, `False`. "f"Got {allow_incomplete_fold}.")ifcv_name=="OneStepAheadFold":ifnotisinstance(initial_train_size,(int,np.integer,str,pd.Timestamp)):raiseValueError(f"`initial_train_size` must be an integer greater than 0, a date "f"string, or a pandas Timestamp. Got {initial_train_size}.")ifisinstance(initial_train_size,(int,np.integer))andinitial_train_size<1:raiseValueError(f"`initial_train_size` must be an integer greater than 0, "f"a date string, or a pandas Timestamp. Got {initial_train_size}.")if(notisinstance(window_size,(int,np.integer,pd.DateOffset,type(None)))orisinstance(window_size,(int,np.integer))andwindow_size<1):raiseValueError(f"`window_size` must be an integer greater than 0. Got {window_size}.")ifdifferentiationisnotNone:ifnotisinstance(differentiation,(int,np.integer))ordifferentiation<0:raiseValueError(f"`differentiation` must be None or an integer greater than or "f"equal to 0. Got {differentiation}.")ifnotisinstance(return_all_indexes,bool):raiseTypeError(f"`return_all_indexes` must be a boolean: `True`, `False`. "f"Got {return_all_indexes}.")ifnotisinstance(verbose,bool):raiseTypeError(f"`verbose` must be a boolean: `True`, `False`. "f"Got {verbose}.")
def_extract_index(self,X:pd.Series|pd.DataFrame|pd.Index|dict[str,pd.Series|pd.DataFrame])->pd.Index:""" Extracts and returns the index from the input data X. Parameters ---------- X : pandas Series, pandas DataFrame, pandas Index, dict Time series data or index to split. Returns ------- idx : pandas Index Index extracted from the input data. """ifisinstance(X,(pd.Series,pd.DataFrame)):idx=X.indexelifisinstance(X,dict):indexes_freq=set()not_valid_index=[]min_index=[]max_index=[]fork,vinX.items():ifvisNone:continueidx=v.indexifisinstance(idx,pd.DatetimeIndex):indexes_freq.add(idx.freq)elifisinstance(idx,pd.RangeIndex):indexes_freq.add(idx.step)else:not_valid_index.append(k)min_index.append(idx[0])max_index.append(idx[-1])ifnot_valid_index:raiseTypeError(f"If `X` is a dictionary, all series must have a Pandas "f"RangeIndex or DatetimeIndex with the same step/frequency. "f"Review series: {not_valid_index}")ifNoneinindexes_freq:raiseValueError("If `X` is a dictionary, all series must have a Pandas ""RangeIndex or DatetimeIndex with the same step/frequency. ""Found series with no frequency or step.")ifnotlen(indexes_freq)==1:raiseValueError(f"If `X` is a dictionary, all series must have a Pandas "f"RangeIndex or DatetimeIndex with the same step/frequency. "f"Found frequencies: {sorted(indexes_freq)}")ifisinstance(idx,pd.DatetimeIndex):idx=pd.date_range(start=min(min_index),end=max(max_index),freq=indexes_freq.pop())else:idx=pd.RangeIndex(start=min(min_index),stop=max(max_index)+1,step=indexes_freq.pop())else:idx=Xreturnidx
defset_params(self,params:dict)->None:""" Set the parameters of the Fold object. Before overwriting the current parameters, the input parameters are validated to ensure correctness. Parameters ---------- params : dict Dictionary with the parameters to set. Returns ------- None """ifnotisinstance(params,dict):raiseTypeError(f"`params` must be a dictionary. Got {type(params)}.")current_params=deepcopy(vars(self))unknown_params=set(params.keys())-set(current_params.keys())ifunknown_params:warnings.warn(f"Unknown parameters: {unknown_params}. They have been ignored.",IgnoredArgumentWarning)filtered_params={k:vfork,vinparams.items()ifkincurrent_params}updated_params={'cv_name':type(self).__name__,**current_params,**filtered_params}self._validate_params(**updated_params)forkey,valueinupdated_params.items():setattr(self,key,value)
Class to split time series data into train and test folds.
When used within a backtesting or hyperparameter search, the arguments
'initial_train_size', 'window_size' and 'differentiation' are not required
as they are automatically set by the backtesting or hyperparameter search
functions.
For example, if skip_folds=3 and there are 10 folds, the returned folds are
0, 3, 6, and 9. If skip_folds=[1, 2, 3], the returned folds are 0, 4, 5, 6, 7,
8, and 9.
Whether to print information about generated folds.
Notes
Returned values are the positions of the observations and not the actual values of
the index, so they can be used to slice the data directly using iloc. For example,
if the input series is X = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], the
initial_train_size = 3, window_size = 2, steps = 4, and gap = 1,
the output of the first fold will: [0, [0, 3], [1, 3], [3, 8], [4, 8], True].
The first element is the fold number, the first list [0, 3] indicates that
the training set goes from the first to the third observation. The second
list [1, 3] indicates that the last window seen by the forecaster during
training goes from the second to the third observation. The third list [3, 8]
indicates that the test set goes from the fourth to the eighth observation.
The fourth list [4, 8] indicates that the test set including the gap goes
from the fifth to the eighth observation. The boolean False indicates that
the forecaster should not be trained in this fold.
Following the python convention, the start index is inclusive and the end index is
exclusive. This means that the last index is not included in the slice.
As an example, with initial_train_size=50, steps=30, and fold_stride=7,
the first test fold will cover observations [50, 80), the second fold [57, 87),
and the third fold [64, 94). This configuration produces multiple forecasts
for the same observations, which is often desirable in rolling-origin
evaluation.
If True, the folds are returned as a DataFrame. This is useful to visualize
the folds in a more interpretable way.
False
Returns:
Name
Type
Description
folds
list, pandas DataFrame
A list of lists containing the indices (position) for each fold. Each list
contains 4 lists and a boolean with the following information:
fold: fold number.
[train_start, train_end]: list with the start and end positions of the
training set.
[last_window_start, last_window_end]: list with the start and end positions
of the last window seen by the forecaster during training. The last window
is used to generate the lags use as predictors. If differentiation is
included, the interval is extended as many observations as the
differentiation order. If the argument window_size is None, this list is
empty.
[test_start, test_end]: list with the start and end positions of the test
set. These are the observations used to evaluate the forecaster.
[test_start_with_gap, test_end_with_gap]: list with the start and end
positions of the test set including the gap. The gap is the number of
observations between the end of the training set and the start of the test
set.
fit_forecaster: boolean indicating whether the forecaster should be fitted
in this fold.
It is important to note that the returned values are the positions of the
observations and not the actual values of the index, so they can be used to
slice the data directly using iloc.
If as_pandas is True, the folds are returned as a DataFrame with the
following columns: 'fold', 'train_start', 'train_end', 'last_window_start',
'last_window_end', 'test_start', 'test_end', 'test_start_with_gap',
'test_end_with_gap', 'fit_forecaster'.
Following the python convention, the start index is inclusive and the end
index is exclusive. This means that the last index is not included in the
slice.
Source code in skforecast\model_selection\_split.py
defsplit(self,X:pd.Series|pd.DataFrame|pd.Index|dict[str,pd.Series|pd.DataFrame],as_pandas:bool=False)->list|pd.DataFrame:""" Split the time series data into train and test folds. Parameters ---------- X : pandas Series, pandas DataFrame, pandas Index, dict Time series data or index to split. as_pandas : bool, default False If True, the folds are returned as a DataFrame. This is useful to visualize the folds in a more interpretable way. Returns ------- folds : list, pandas DataFrame A list of lists containing the indices (position) for each fold. Each list contains 4 lists and a boolean with the following information: - fold: fold number. - [train_start, train_end]: list with the start and end positions of the training set. - [last_window_start, last_window_end]: list with the start and end positions of the last window seen by the forecaster during training. The last window is used to generate the lags use as predictors. If `differentiation` is included, the interval is extended as many observations as the differentiation order. If the argument `window_size` is `None`, this list is empty. - [test_start, test_end]: list with the start and end positions of the test set. These are the observations used to evaluate the forecaster. - [test_start_with_gap, test_end_with_gap]: list with the start and end positions of the test set including the gap. The gap is the number of observations between the end of the training set and the start of the test set. - fit_forecaster: boolean indicating whether the forecaster should be fitted in this fold. It is important to note that the returned values are the positions of the observations and not the actual values of the index, so they can be used to slice the data directly using iloc. If `as_pandas` is `True`, the folds are returned as a DataFrame with the following columns: 'fold', 'train_start', 'train_end', 'last_window_start', 'last_window_end', 'test_start', 'test_end', 'test_start_with_gap', 'test_end_with_gap', 'fit_forecaster'. Following the python convention, the start index is inclusive and the end index is exclusive. This means that the last index is not included in the slice. """ifnotisinstance(X,(pd.Series,pd.DataFrame,pd.Index,dict)):raiseTypeError(f"X must be a pandas Series, DataFrame, Index or a dictionary. "f"Got {type(X)}.")window_size_as_date_offset=isinstance(self.window_size,pd.tseries.offsets.DateOffset)ifwindow_size_as_date_offset:# Calculate the window_size in steps. This is not a exact calculation# because the offset follows the calendar rules and the distance between# two dates may not be constant.first_valid_index=X.index[-1]-self.window_sizetry:window_size_idx_start=X.index.get_loc(first_valid_index)window_size_idx_end=X.index.get_loc(X.index[-1])self.window_size=window_size_idx_end-window_size_idx_startexceptKeyError:raiseValueError(f"The length of `y` ({len(X)}), must be greater than or equal "f"to the window size ({self.window_size}). This is because "f"the offset (forecaster.offset) is larger than the available "f"data. Try to decrease the size of the offset (forecaster.offset), "f"the number of `n_offsets` (forecaster.n_offsets) or increase the "f"size of `y`.")ifself.initial_train_sizeisNone:ifself.window_sizeisNone:raiseValueError("To use split method when `initial_train_size` is None, ""`window_size` must be an integer greater than 0. ""Although no initial training is done and all data is used to ""evaluate the model, the first `window_size` observations are ""needed to create the initial predictors. Got `window_size` = None.")ifself.refit:raiseValueError("`refit` is only allowed when `initial_train_size` is not `None`. ""Set `refit` to `False` if you want to use `initial_train_size = None`.")externally_fitted=Trueself.initial_train_size=self.window_size# Reset to None laterelse:ifself.window_sizeisNone:warnings.warn("Last window cannot be calculated because `window_size` is None.",IgnoredArgumentWarning)externally_fitted=Falseindex=self._extract_index(X)idx=range(len(index))folds=[]i=0self.initial_train_size=date_to_index_position(index=index,date_input=self.initial_train_size,method='validation',date_literal='initial_train_size')ifwindow_size_as_date_offset:ifself.initial_train_sizeisnotNone:ifself.initial_train_size<self.window_size:raiseValueError(f"If `initial_train_size` is an integer, it must be greater than "f"the `window_size` of the forecaster ({self.window_size}) "f"and smaller than the length of the series ({len(X)}). If "f"it is a date, it must be within this range of the index.")ifself.allow_incomplete_fold:# At least one observation after the gap to allow incomplete foldiflen(index)<=self.initial_train_size+self.gap:raiseValueError(f"The time series must have more than `initial_train_size + gap` "f"observations to create at least one fold.\n"f" Time series length: {len(index)}\n"f" Required > {self.initial_train_size+self.gap}\n"f" initial_train_size: {self.initial_train_size}\n"f" gap: {self.gap}\n")else:# At least one complete foldiflen(index)<self.initial_train_size+self.gap+self.steps:raiseValueError(f"The time series must have at least `initial_train_size + gap + steps` "f"observations to create a minimum of one complete fold "f"(allow_incomplete_fold=False).\n"f" Time series length: {len(index)}\n"f" Required >= {self.initial_train_size+self.gap+self.steps}\n"f" initial_train_size: {self.initial_train_size}\n"f" gap: {self.gap}\n"f" steps: {self.steps}\n")whileself.initial_train_size+(i*self.fold_stride)+self.gap<len(index):ifself.refit:# NOTE: If `fixed_train_size` the train size doesn't increase but # moves by `fold_stride` positions in each iteration. If `False`, # the train size increases by `fold_stride` in each iteration.train_iloc_start=i*(self.fold_stride)ifself.fixed_train_sizeelse0train_iloc_end=self.initial_train_size+i*(self.fold_stride)test_iloc_start=train_iloc_endelse:# NOTE: The train size doesn't increase and doesn't move.train_iloc_start=0train_iloc_end=self.initial_train_sizetest_iloc_start=self.initial_train_size+i*(self.fold_stride)ifself.window_sizeisnotNone:last_window_iloc_start=test_iloc_start-self.window_sizetest_iloc_end=test_iloc_start+self.gap+self.stepspartitions=[idx[train_iloc_start:train_iloc_end],idx[last_window_iloc_start:test_iloc_start]ifself.window_sizeisnotNoneelse[],idx[test_iloc_start:test_iloc_end],idx[test_iloc_start+self.gap:test_iloc_end]]folds.append(partitions)i+=1# NOTE: Delete all incomplete folds at the end if not allowedn_removed_folds=0ifnotself.allow_incomplete_fold:# NOTE: While folds and the last "test_index_with_gap" is incomplete,# calculating len of range objectswhilefoldsandlen(folds[-1][3])<self.steps:folds.pop()n_removed_folds+=1# Replace partitions inside folds with length 0 with `None`folds=[[partitioniflen(partition)>0elseNoneforpartitioninfold]forfoldinfolds]# Create a flag to know whether to train the forecasterifself.refit==0:self.refit=Falseifisinstance(self.refit,bool):fit_forecaster=[self.refit]*len(folds)fit_forecaster[0]=Trueelse:fit_forecaster=[False]*len(folds)foriinrange(0,len(fit_forecaster),self.refit):fit_forecaster[i]=Trueforiinrange(len(folds)):folds[i].insert(0,i)folds[i].append(fit_forecaster[i])iffit_forecaster[i]isFalse:folds[i][1]=folds[i-1][1]index_to_skip=[]ifself.skip_foldsisnotNone:ifisinstance(self.skip_folds,(int,np.integer))andself.skip_folds>0:index_to_keep=np.arange(0,len(folds),self.skip_folds)index_to_skip=np.setdiff1d(np.arange(0,len(folds)),index_to_keep,assume_unique=True)index_to_skip=[int(x)forxinindex_to_skip]# Required since numpy 2.0ifisinstance(self.skip_folds,list):index_to_skip=[iforiinself.skip_foldsifi<len(folds)]ifself.verbose:self._print_info(index=index,folds=folds,externally_fitted=externally_fitted,n_removed_folds=n_removed_folds,index_to_skip=index_to_skip)folds=[foldfori,foldinenumerate(folds)ifinotinindex_to_skip]ifnotself.return_all_indexes:# NOTE: +1 to prevent iloc pandas from deleting the last observationfolds=[[fold[0],[fold[1][0],fold[1][-1]+1],([fold[2][0],fold[2][-1]+1]ifself.window_sizeisnotNoneelse[]),[fold[3][0],fold[3][-1]+1],[fold[4][0],fold[4][-1]+1],fold[5],]forfoldinfolds]ifexternally_fitted:self.initial_train_size=Nonefolds[0][5]=Falseifas_pandas:ifself.window_sizeisNone:forfoldinfolds:fold[2]=[None,None]ifnotself.return_all_indexes:folds=pd.DataFrame(data=[[fold[0]]+list(itertools.chain(*fold[1:-1]))+[fold[-1]]forfoldinfolds],columns=['fold','train_start','train_end','last_window_start','last_window_end','test_start','test_end','test_start_with_gap','test_end_with_gap','fit_forecaster'],)else:folds=pd.DataFrame(data=folds,columns=['fold','train_index','last_window_index','test_index','test_index_with_gap','fit_forecaster'],)returnfolds
def_print_info(self,index:pd.Index,folds:list[list[int]],externally_fitted:bool,n_removed_folds:int,index_to_skip:list[int])->None:""" Print information about folds. Parameters ---------- index : pandas Index Index of the time series data. folds : list A list of lists containing the indices (position) for each fold. externally_fitted : bool Whether an already trained forecaster is to be used. n_removed_folds : int Number of folds removed. index_to_skip : list Number of folds skipped. Returns ------- None """print("Information of folds")print("--------------------")ifexternally_fitted:print(f"An already trained forecaster is to be used. Window size: "f"{self.window_size}")else:ifself.differentiationisNone:print(f"Number of observations used for initial training: "f"{self.initial_train_size}")else:print(f"Number of observations used for initial training: "f"{self.initial_train_size-self.differentiation}")print(f" First {self.differentiation} observation/s in training sets "f"are used for differentiation")print(f"Number of observations used for backtesting: "f"{len(index)-self.initial_train_size}")print(f" Number of folds: {len(folds)}")print(f" Number skipped folds: "f"{len(index_to_skip)}{index_to_skipifindex_to_skipelse''}")print(f" Number of steps per fold: {self.steps}")ifself.steps!=self.fold_stride:print(f" Number of steps to the next fold (fold stride): {self.fold_stride}")print(f" Number of steps to exclude between last observed data "f"(last window) and predictions (gap): {self.gap}")ifn_removed_folds>0:print(f" The last {n_removed_folds} fold(s) have been excluded "f"because they were incomplete.")iflen(folds[-1][4])<self.steps:print(f" Last fold only includes {len(folds[-1][4])} observations.")print("")ifself.differentiationisNone:differentiation=0else:differentiation=self.differentiationfori,foldinenumerate(folds):is_fold_skipped=iinindex_to_skiphas_training=fold[-1]ifi!=0elseTruetraining_start=(index[fold[1][0]+differentiation]iffold[1]isnotNoneelseNone)training_end=index[fold[1][-1]]iffold[1]isnotNoneelseNonetraining_length=(len(fold[1])-differentiationiffold[1]isnotNoneelse0)validation_start=index[fold[4][0]]validation_end=index[fold[4][-1]]validation_length=len(fold[4])print(f"Fold: {i}")ifis_fold_skipped:print(" Fold skipped")elifnotexternally_fittedandhas_training:print(f" Training: {training_start} -- {training_end} "f"(n={training_length})")print(f" Validation: {validation_start} -- {validation_end} "f"(n={validation_length})")else:print(" Training: No training in this fold")print(f" Validation: {validation_start} -- {validation_end} "f"(n={validation_length})")print("")
This argument is not used in this class. It is included for API consistency.
None
Returns:
Name
Type
Description
fold
list, pandas DataFrame
A list of lists containing the indices (position) of the fold. The list
contains 2 lists with the following information:
fold: fold number.
[train_start, train_end]: list with the start and end positions of the
training set.
[test_start, test_end]: list with the start and end positions of the test
set. These are the observations used to evaluate the forecaster.
fit_forecaster: boolean indicating whether the forecaster should be fitted
in this fold.
It is important to note that the returned values are the positions of the
observations and not the actual values of the index, so they can be used to
slice the data directly using iloc.
If as_pandas is True, the folds are returned as a DataFrame with the
following columns: 'fold', 'train_start', 'train_end', 'test_start',
'test_end', 'fit_forecaster'.
Following the python convention, the start index is inclusive and the end
index is exclusive. This means that the last index is not included in the
slice.
Source code in skforecast\model_selection\_split.py
defsplit(self,X:pd.Series|pd.DataFrame|pd.Index|dict[str,pd.Series|pd.DataFrame],as_pandas:bool=False,externally_fitted:Any=None)->list|pd.DataFrame:""" Split the time series data into train and test folds. Parameters ---------- X : pandas Series, DataFrame, Index, or dictionary Time series data or index to split. as_pandas : bool, default False If True, the folds are returned as a DataFrame. This is useful to visualize the folds in a more interpretable way. externally_fitted : Any This argument is not used in this class. It is included for API consistency. Returns ------- fold : list, pandas DataFrame A list of lists containing the indices (position) of the fold. The list contains 2 lists with the following information: - fold: fold number. - [train_start, train_end]: list with the start and end positions of the training set. - [test_start, test_end]: list with the start and end positions of the test set. These are the observations used to evaluate the forecaster. - fit_forecaster: boolean indicating whether the forecaster should be fitted in this fold. It is important to note that the returned values are the positions of the observations and not the actual values of the index, so they can be used to slice the data directly using iloc. If `as_pandas` is `True`, the folds are returned as a DataFrame with the following columns: 'fold', 'train_start', 'train_end', 'test_start', 'test_end', 'fit_forecaster'. Following the python convention, the start index is inclusive and the end index is exclusive. This means that the last index is not included in the slice. """ifnotisinstance(X,(pd.Series,pd.DataFrame,pd.Index,dict)):raiseTypeError(f"X must be a pandas Series, DataFrame, Index or a dictionary. "f"Got {type(X)}.")index=self._extract_index(X)self.initial_train_size=date_to_index_position(index=index,date_input=self.initial_train_size,method='validation',date_literal='initial_train_size')fold=[0,[0,self.initial_train_size-1],[self.initial_train_size,len(X)],True]ifself.verbose:self._print_info(index=index,fold=fold)# NOTE: +1 to prevent iloc pandas from deleting the last observationifself.return_all_indexes:fold=[fold[0],[range(fold[1][0],fold[1][1]+1)],[range(fold[2][0],fold[2][1])],fold[3]]else:fold=[fold[0],[fold[1][0],fold[1][1]+1],[fold[2][0],fold[2][1]],fold[3]]ifas_pandas:ifnotself.return_all_indexes:fold=pd.DataFrame(data=[[fold[0]]+list(itertools.chain(*fold[1:-1]))+[fold[-1]]],columns=['fold','train_start','train_end','test_start','test_end','fit_forecaster'],)else:fold=pd.DataFrame(data=[fold],columns=['fold','train_index','test_index','fit_forecaster'],)returnfold
def_print_info(self,index:pd.Index,fold:list[list[int]])->None:""" Print information about folds. Parameters ---------- index : pandas Index Index of the time series data. fold : list A list of lists containing the indices (position) of the fold. Returns ------- None """ifself.differentiationisNone:differentiation=0else:differentiation=self.differentiationinitial_train_size=self.initial_train_size-differentiationtest_length=len(index)-(initial_train_size+differentiation)print("Information of folds")print("--------------------")print(f"Number of observations in train: {initial_train_size}")ifself.differentiationisnotNone:print(f" First {differentiation} observation/s in training set "f"are used for differentiation")print(f"Number of observations in test: {test_length}")training_start=index[fold[1][0]+differentiation]training_end=index[fold[1][-1]]test_start=index[fold[2][0]]test_end=index[fold[2][-1]-1]print(f"Training : {training_start} -- {training_end} (n={initial_train_size})")print(f"Test : {test_start} -- {test_end} (n={test_length})")print("")
Lists of lags to try, containing int, lists, numpy ndarray, or range
objects. If dict, the keys are used as labels in the results
DataFrame, and the values are used as the lists of lags to try.
definitialize_lags_grid(forecaster:object,lags_grid:(list[int|list[int]|np.ndarray[int]|range[int]]|dict[str,list[int|list[int]|np.ndarray[int]|range[int]]]|None)=None,)->tuple[dict[str,int],str]:""" Initialize lags grid and lags label for model selection. Parameters ---------- forecaster : Forecaster Forecaster model. ForecasterRecursive, ForecasterDirect, ForecasterRecursiveMultiSeries, ForecasterDirectMultiVariate. lags_grid : list, dict, default None Lists of lags to try, containing int, lists, numpy ndarray, or range objects. If `dict`, the keys are used as labels in the `results` DataFrame, and the values are used as the lists of lags to try. Returns ------- lags_grid : dict Dictionary with lags configuration for each iteration. lags_label : str Label for lags representation in the results object. """ifnotisinstance(lags_grid,(list,dict,type(None))):raiseTypeError(f"`lags_grid` argument must be a list, dict or None. "f"Got {type(lags_grid)}.")lags_label='values'ifisinstance(lags_grid,list):lags_grid={f'{lags}':lagsforlagsinlags_grid}eliflags_gridisNone:lags=[int(lag)forlaginforecaster.lags]# Required since numpy 2.0lags_grid={f'{lags}':lags}else:lags_label='keys'returnlags_grid,lags_label
Specifies whether probabilistic predictions should be estimated and the
method to use. The following options are supported:
If float, represents the nominal (expected) coverage (between 0 and 1).
For instance, interval=0.95 corresponds to [2.5, 97.5] percentiles.
If list or tuple: Sequence of percentiles to compute, each value must
be between 0 and 100 inclusive. For example, a 95% confidence interval can
be specified as interval = [2.5, 97.5] or multiple percentiles (e.g. 10,
50 and 90) as interval = [10, 50, 90].
If 'bootstrapping' (str): n_boot bootstrapping predictions will be generated.
If scipy.stats distribution object, the distribution parameters will
be estimated for each prediction.
If None, no probabilistic predictions are estimated.
If True, residuals from the training data are used as proxy of prediction
error to create prediction intervals. If False, out_sample_residuals
are used if they are already stored inside the forecaster.
The number of jobs to run in parallel. If -1, then the number of jobs is
set to the number of cores. If 'auto', n_jobs is set using the function
skforecast.utils.select_n_jobs_fit_forecaster.
If True, skforecast warnings will be suppressed during the backtesting
process. See skforecast.exceptions.warn_skforecast_categories for more
information.
defcheck_backtesting_input(forecaster:object,cv:object,metric:str|Callable|list[str|Callable],add_aggregated_metric:bool=True,y:pd.Series|None=None,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame]=None,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,interval:float|list[float]|tuple[float]|str|object|None=None,interval_method:str='bootstrapping',alpha:float|None=None,n_boot:int=250,use_in_sample_residuals:bool=True,use_binned_residuals:bool=True,random_state:int=123,return_predictors:bool=False,n_jobs:int|str='auto',show_progress:bool=True,suppress_warnings:bool=False,suppress_warnings_fit:bool=False)->None:""" This is a helper function to check most inputs of backtesting functions in modules `model_selection`. Parameters ---------- forecaster : Forecaster Forecaster model. cv : TimeSeriesFold TimeSeriesFold object with the information needed to split the data into folds. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. add_aggregated_metric : bool, default True If `True`, the aggregated metrics (average, weighted average and pooling) over all levels are also returned (only multiseries). y : pandas Series, default None Training time series for uni-series forecasters. series : pandas DataFrame, dict, default None Training time series for multi-series forecasters. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. interval : float, list, tuple, str, object, default None Specifies whether probabilistic predictions should be estimated and the method to use. The following options are supported: - If `float`, represents the nominal (expected) coverage (between 0 and 1). For instance, `interval=0.95` corresponds to `[2.5, 97.5]` percentiles. - If `list` or `tuple`: Sequence of percentiles to compute, each value must be between 0 and 100 inclusive. For example, a 95% confidence interval can be specified as `interval = [2.5, 97.5]` or multiple percentiles (e.g. 10, 50 and 90) as `interval = [10, 50, 90]`. - If 'bootstrapping' (str): `n_boot` bootstrapping predictions will be generated. - If scipy.stats distribution object, the distribution parameters will be estimated for each prediction. - If None, no probabilistic predictions are estimated. interval_method : str, default 'bootstrapping' Technique used to estimate prediction intervals. Available options: + 'bootstrapping': Bootstrapping is used to generate prediction intervals. + 'conformal': Employs the conformal prediction split method for interval estimation. alpha : float, default None The confidence intervals used in ForecasterStats are (1 - alpha) %. n_boot : int, default `250` Number of bootstrapping iterations to perform when estimating prediction intervals. use_in_sample_residuals : bool, default True If `True`, residuals from the training data are used as proxy of prediction error to create prediction intervals. If `False`, out_sample_residuals are used if they are already stored inside the forecaster. use_binned_residuals : bool, default True If `True`, residuals are selected based on the predicted values (binned selection). If `False`, residuals are selected randomly. random_state : int, default `123` Seed for the random number generator to ensure reproducibility. return_predictors : bool, default False If `True`, the predictors used to make the predictions are also returned. n_jobs : int, 'auto', default `'auto'` The number of jobs to run in parallel. If `-1`, then the number of jobs is set to the number of cores. If 'auto', `n_jobs` is set using the function skforecast.utils.select_n_jobs_fit_forecaster. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the backtesting process. See skforecast.exceptions.warn_skforecast_categories for more information. suppress_warnings_fit : bool, default False If `True`, warnings generated during fitting will be ignored. Only `ForecasterStats`. Returns ------- None """forecaster_name=type(forecaster).__name__cv_name=type(cv).__name__ifcv_name!="TimeSeriesFold":raiseTypeError(f"`cv` must be a 'TimeSeriesFold' object. Got '{cv_name}'.")steps=cv.stepsinitial_train_size=cv.initial_train_sizegap=cv.gapallow_incomplete_fold=cv.allow_incomplete_foldrefit=cv.refitforecasters_uni=["ForecasterRecursive","ForecasterDirect","ForecasterStats","ForecasterEquivalentDate","ForecasterRecursiveClassifier"]forecasters_direct=["ForecasterDirect","ForecasterDirectMultiVariate","ForecasterRnn"]forecasters_multi_no_dict=["ForecasterDirectMultiVariate","ForecasterRnn",]forecasters_multi_dict=["ForecasterRecursiveMultiSeries"]# NOTE: ForecasterStats has interval but not with bootstrapping or conformalforecasters_boot_conformal=["ForecasterRecursive","ForecasterDirect","ForecasterRecursiveMultiSeries","ForecasterDirectMultiVariate","ForecasterEquivalentDate",]forecasters_return_predictors=["ForecasterRecursive","ForecasterDirect","ForecasterRecursiveMultiSeries","ForecasterDirectMultiVariate","ForecasterRecursiveClassifier"]ifforecaster_nameinforecasters_uni:ifnotisinstance(y,pd.Series):raiseTypeError("`y` must be a pandas Series.")data_name='y'data_length=len(y)elifforecaster_nameinforecasters_multi_no_dict:ifnotisinstance(series,pd.DataFrame):raiseTypeError("`series` must be a pandas DataFrame.")data_name='series'data_length=len(series)elifforecaster_nameinforecasters_multi_dict:# NOTE: Checks are not need as they are done in the function # `check_preprocess_series` that is used before `check_backtesting_input`# in the backtesting function.data_name='series'data_length=max([len(series[serie])forserieinseries])ifexogisnotNone:ifforecaster_nameinforecasters_multi_dict:# NOTE: Checks are not need as they are done in the function # `check_preprocess_exog_multiseries` that is used before # `check_backtesting_input` in the backtesting function.passelse:ifnotisinstance(exog,(pd.Series,pd.DataFrame)):raiseTypeError(f"`exog` must be a pandas Series, DataFrame or None. Got {type(exog)}.")ifhasattr(forecaster,'differentiation'):ifforecaster.differentiation_max!=cv.differentiation:ifforecaster_name=="ForecasterRecursiveMultiSeries"andisinstance(forecaster.differentiation,dict):raiseValueError(f"When using a dict as `differentiation` in ForecasterRecursiveMultiSeries, "f"the `differentiation` included in the cv ({cv.differentiation}) must be "f"the same as the maximum `differentiation` included in the forecaster "f"({forecaster.differentiation_max}). Set the same value "f"for both using the `differentiation` argument.")else:raiseValueError(f"The differentiation included in the forecaster "f"({forecaster.differentiation_max}) differs from the differentiation "f"included in the cv ({cv.differentiation}). Set the same value "f"for both using the `differentiation` argument.")ifnotisinstance(metric,(str,Callable,list)):raiseTypeError(f"`metric` must be a string, a callable function, or a list containing "f"multiple strings and/or callables. Got {type(metric)}.")ifforecaster_name=="ForecasterEquivalentDate"andisinstance(forecaster.offset,pd.tseries.offsets.DateOffset):# NOTE: Checks when initial_train_size is not None cannot be done here# because the forecaster is not fitted yet and we don't know the# window_size since pd.DateOffset is not a fixed window size.ifinitial_train_sizeisNone:raiseValueError(f"`initial_train_size` must be an integer greater than "f"the `window_size` of the forecaster ({forecaster.window_size}) "f"and smaller than the length of `{data_name}` ({data_length}) or "f"a date within this range of the index.")elifinitial_train_sizeisnotNone:ifforecaster_nameinforecasters_uni:index=cv._extract_index(y)else:index=cv._extract_index(series)initial_train_size=date_to_index_position(index=index,date_input=initial_train_size,method='validation',date_literal='initial_train_size')ifinitial_train_size<forecaster.window_sizeorinitial_train_size>=data_length:raiseValueError(f"If `initial_train_size` is an integer, it must be greater than "f"the `window_size` of the forecaster ({forecaster.window_size}) "f"and smaller than the length of `{data_name}` ({data_length}). If "f"it is a date, it must be within this range of the index.")ifallow_incomplete_fold:# At least one observation after the gap to allow incomplete foldifdata_length<=initial_train_size+gap:raiseValueError(f"`{data_name}` must have more than `initial_train_size + gap` "f"observations to create at least one fold.\n"f" Time series length: {data_length}\n"f" Required > {initial_train_size+gap}\n"f" initial_train_size: {initial_train_size}\n"f" gap: {gap}\n")else:# At least one complete foldifdata_length<initial_train_size+gap+steps:raiseValueError(f"`{data_name}` must have at least `initial_train_size + gap + steps` "f"observations to create a minimum of one complete fold "f"(allow_incomplete_fold=False).\n"f" Time series length: {data_length}\n"f" Required >= {initial_train_size+gap+steps}\n"f" initial_train_size: {initial_train_size}\n"f" gap: {gap}\n"f" steps: {steps}\n")else:ifforecaster_namein['ForecasterStats','ForecasterEquivalentDate']:raiseValueError(f"`initial_train_size` must be an integer smaller than the "f"length of `{data_name}` ({data_length}).")else:ifnotforecaster.is_fitted:raiseNotFittedError("`forecaster` must be already trained if no `initial_train_size` ""is provided.")ifrefit:raiseValueError("`refit` is only allowed when `initial_train_size` is not `None`.")ifforecaster_name=='ForecasterStats'andcv.skip_foldsisnotNone:raiseValueError("`skip_folds` is not allowed for ForecasterStats. Set it to `None`.")ifnotisinstance(add_aggregated_metric,bool):raiseTypeError("`add_aggregated_metric` must be a boolean: `True`, `False`.")ifnotisinstance(n_boot,(int,np.integer))orn_boot<0:raiseTypeError(f"`n_boot` must be an integer greater than 0. Got {n_boot}.")ifnotisinstance(use_in_sample_residuals,bool):raiseTypeError("`use_in_sample_residuals` must be a boolean: `True`, `False`.")ifnotisinstance(use_binned_residuals,bool):raiseTypeError("`use_binned_residuals` must be a boolean: `True`, `False`.")ifnotisinstance(random_state,(int,np.integer))orrandom_state<0:raiseTypeError(f"`random_state` must be an integer greater than 0. Got {random_state}.")ifnotisinstance(return_predictors,bool):raiseTypeError("`return_predictors` must be a boolean: `True`, `False`.")ifnotisinstance(n_jobs,int)andn_jobs!='auto':raiseTypeError(f"`n_jobs` must be an integer or `'auto'`. Got {n_jobs}.")ifnotisinstance(show_progress,bool):raiseTypeError("`show_progress` must be a boolean: `True`, `False`.")ifnotisinstance(suppress_warnings,bool):raiseTypeError("`suppress_warnings` must be a boolean: `True`, `False`.")ifnotisinstance(suppress_warnings_fit,bool):raiseTypeError("`suppress_warnings_fit` must be a boolean: `True`, `False`.")ifintervalisnotNoneoralphaisnotNone:ifforecaster_nameinforecasters_boot_conformal:ifinterval_method=='conformal':ifnotisinstance(interval,(float,list,tuple)):raiseTypeError(f"When `interval_method` is 'conformal', `interval` must "f"be a float or a list/tuple defining a symmetric interval. "f"Got {type(interval)}.")elifinterval_method=='bootstrapping':if(notisinstance(interval,(float,list,tuple,str))and(nothasattr(interval,"_pdf")ornotcallable(getattr(interval,"fit",None)))):raiseTypeError(f"When `interval_method` is 'bootstrapping', `interval` "f"must be a float, a list or tuple of floats, a "f"scipy.stats distribution object (with methods `_pdf` and "f"`fit`) or the string 'bootstrapping'. Got {type(interval)}.")ifisinstance(interval,(list,tuple)):foriininterval:ifnotisinstance(i,(int,float)):raiseTypeError(f"`interval` must be a list or tuple of floats. "f"Got {type(i)} in {interval}.")iflen(interval)==2:check_interval(interval=interval)else:forqininterval:if(q<0.)or(q>100.):raiseValueError("When `interval` is a list or tuple, all values must be ""between 0 and 100 inclusive.")elifisinstance(interval,str):ifinterval!='bootstrapping':raiseValueError(f"When `interval` is a string, it must be 'bootstrapping'."f"Got {interval}.")else:raiseValueError(f"`interval_method` must be 'bootstrapping' or 'conformal'. "f"Got {interval_method}.")else:ifforecaster_name=='ForecasterRecursiveClassifier':raiseValueError(f"`interval` is not supported for {forecaster_name}. Class "f"probabilities are returned by default during backtesting, "f"set `interval=None`.")check_interval(interval=interval,alpha=alpha)ifreturn_predictorsandforecaster_namenotinforecasters_return_predictors:raiseValueError(f"`return_predictors` is only allowed for forecasters of type "f"{forecasters_return_predictors}. Got {forecaster_name}.")ifforecaster_nameinforecasters_directandforecaster.max_step<steps+gap:raiseValueError(f"When using a {forecaster_name}, the combination of steps "f"+ gap ({steps+gap}) cannot be greater than the `steps` parameter "f"declared when the forecaster is initialized ({forecaster.max_step}).")
If True, skforecast warnings will be suppressed during the hyperparameter
search. See skforecast.exceptions.warn_skforecast_categories for more
information.
False
Returns:
Type
Description
None
Source code in skforecast\model_selection\_utils.py
defcheck_one_step_ahead_input(forecaster:object,cv:object,metric:str|Callable|list[str|Callable],y:pd.Series|None=None,series:pd.DataFrame|dict[str,pd.Series|pd.DataFrame]=None,exog:pd.Series|pd.DataFrame|dict[str,pd.Series|pd.DataFrame]|None=None,show_progress:bool=True,suppress_warnings:bool=False)->None:""" This is a helper function to check most inputs of hyperparameter tuning functions in modules `model_selection` when using a `OneStepAheadFold`. Parameters ---------- forecaster : Forecaster Forecaster model. cv : OneStepAheadFold OneStepAheadFold object with the information needed to split the data into folds. metric : str, Callable, list Metric used to quantify the goodness of fit of the model. y : pandas Series, default None Training time series for uni-series forecasters. series : pandas DataFrame, dict, default None Training time series for multi-series forecasters. exog : pandas Series, pandas DataFrame, dict, default None Exogenous variables. show_progress : bool, default True Whether to show a progress bar. suppress_warnings: bool, default False If `True`, skforecast warnings will be suppressed during the hyperparameter search. See skforecast.exceptions.warn_skforecast_categories for more information. Returns ------- None """forecaster_name=type(forecaster).__name__cv_name=type(cv).__name__ifcv_name!="OneStepAheadFold":raiseTypeError(f"`cv` must be a 'OneStepAheadFold' object. Got '{cv_name}'.")initial_train_size=cv.initial_train_sizeforecasters_one_step_ahead=["ForecasterRecursive","ForecasterDirect","ForecasterRecursiveClassifier",'ForecasterRecursiveMultiSeries','ForecasterDirectMultiVariate']ifforecaster_namenotinforecasters_one_step_ahead:raiseTypeError(f"Only forecasters of type {forecasters_one_step_ahead} are allowed "f"when using `cv` of type `OneStepAheadFold`. Got {forecaster_name}.")forecasters_uni=["ForecasterRecursive","ForecasterDirect","ForecasterRecursiveClassifier"]forecasters_multi_no_dict=["ForecasterDirectMultiVariate",]forecasters_multi_dict=["ForecasterRecursiveMultiSeries"]ifforecaster_nameinforecasters_uni:ifnotisinstance(y,pd.Series):raiseTypeError(f"`y` must be a pandas Series. Got {type(y)}")data_name='y'data_length=len(y)elifforecaster_nameinforecasters_multi_no_dict:ifnotisinstance(series,pd.DataFrame):raiseTypeError(f"`series` must be a pandas DataFrame. Got {type(series)}")data_name='series'data_length=len(series)elifforecaster_nameinforecasters_multi_dict:# NOTE: Checks are not need as they are done in the function # `check_preprocess_series` that is used before `check_one_step_ahead_input`# in the backtesting function.data_name='series'data_length=max([len(series[serie])forserieinseries])ifexogisnotNone:ifforecaster_nameinforecasters_multi_dict:# NOTE: Checks are not need as they are done in the function # `check_preprocess_exog_multiseries` that is used before # `check_backtesting_input` in the backtesting function.passelse:ifnotisinstance(exog,(pd.Series,pd.DataFrame)):raiseTypeError(f"`exog` must be a pandas Series, DataFrame or None. Got {type(exog)}.")ifhasattr(forecaster,'differentiation'):ifforecaster.differentiation_max!=cv.differentiation:ifforecaster_name=="ForecasterRecursiveMultiSeries"andisinstance(forecaster.differentiation,dict):raiseValueError(f"When using a dict as `differentiation` in ForecasterRecursiveMultiSeries, "f"the `differentiation` included in the cv ({cv.differentiation}) must be "f"the same as the maximum `differentiation` included in the forecaster "f"({forecaster.differentiation_max}). Set the same value "f"for both using the `differentiation` argument.")else:raiseValueError(f"The differentiation included in the forecaster "f"({forecaster.differentiation_max}) differs from the differentiation "f"included in the cv ({cv.differentiation}). Set the same value "f"for both using the `differentiation` argument.")ifnotisinstance(metric,(str,Callable,list)):raiseTypeError(f"`metric` must be a string, a callable function, or a list containing "f"multiple strings and/or callables. Got {type(metric)}.")ifforecaster_nameinforecasters_uni:index=cv._extract_index(y)else:index=cv._extract_index(series)initial_train_size=date_to_index_position(index=index,date_input=initial_train_size,method='validation',date_literal='initial_train_size')ifinitial_train_size<forecaster.window_sizeorinitial_train_size>=data_length:raiseValueError(f"If `initial_train_size` is an integer, it must be greater than "f"the `window_size` of the forecaster ({forecaster.window_size}) "f"and smaller than the length of `{data_name}` ({data_length}). If "f"it is a date, it must be within this range of the index.")ifnotisinstance(show_progress,bool):raiseTypeError("`show_progress` must be a boolean: `True`, `False`.")ifnotisinstance(suppress_warnings,bool):raiseTypeError("`suppress_warnings` must be a boolean: `True`, `False`.")ifnotsuppress_warnings:warnings.warn("One-step-ahead predictions are used for faster model comparison, but they ""may not fully represent multi-step prediction performance. It is recommended ""to backtest the final model for a more accurate multi-step performance ""estimate.",OneStepAheadValidationWarning)
Select the optimal number of jobs to use in the backtesting process. This
selection is based on heuristics and is not guaranteed to be optimal.
The number of jobs is chosen as follows:
If refit is an integer, then n_jobs = 1. This is because parallelization doesn't
work with intermittent refit.
If forecaster is 'ForecasterRecursive' and estimator is a linear estimator,
then n_jobs = 1.
If forecaster is 'ForecasterRecursive' and estimator is not a linear
estimator then n_jobs = cpu_count() - 1.
If forecaster is 'ForecasterDirect' or 'ForecasterDirectMultiVariate'
and refit = True, then n_jobs = cpu_count() - 1.
If forecaster is 'ForecasterDirect' or 'ForecasterDirectMultiVariate'
and refit = False, then n_jobs = 1.
If forecaster is 'ForecasterRecursiveMultiSeries', then n_jobs = cpu_count() - 1.
If forecaster is 'ForecasterStats' or 'ForecasterEquivalentDate',
then n_jobs = 1.
If estimator is a LGBMRegressor(n_jobs=1), then n_jobs = cpu_count() - 1.
If estimator is a LGBMRegressor with internal n_jobs != 1, then n_jobs = 1.
This is because lightgbm is highly optimized for gradient boosting and
parallelizes operations at a very fine-grained level, making additional
parallelization unnecessary and potentially harmful due to resource contention.
defselect_n_jobs_backtesting(forecaster:object,refit:bool|int)->int:""" Select the optimal number of jobs to use in the backtesting process. This selection is based on heuristics and is not guaranteed to be optimal. The number of jobs is chosen as follows: - If `refit` is an integer, then `n_jobs = 1`. This is because parallelization doesn't work with intermittent refit. - If forecaster is 'ForecasterRecursive' and estimator is a linear estimator, then `n_jobs = 1`. - If forecaster is 'ForecasterRecursive' and estimator is not a linear estimator then `n_jobs = cpu_count() - 1`. - If forecaster is 'ForecasterDirect' or 'ForecasterDirectMultiVariate' and `refit = True`, then `n_jobs = cpu_count() - 1`. - If forecaster is 'ForecasterDirect' or 'ForecasterDirectMultiVariate' and `refit = False`, then `n_jobs = 1`. - If forecaster is 'ForecasterRecursiveMultiSeries', then `n_jobs = cpu_count() - 1`. - If forecaster is 'ForecasterStats' or 'ForecasterEquivalentDate', then `n_jobs = 1`. - If estimator is a `LGBMRegressor(n_jobs=1)`, then `n_jobs = cpu_count() - 1`. - If estimator is a `LGBMRegressor` with internal n_jobs != 1, then `n_jobs = 1`. This is because `lightgbm` is highly optimized for gradient boosting and parallelizes operations at a very fine-grained level, making additional parallelization unnecessary and potentially harmful due to resource contention. Parameters ---------- forecaster : Forecaster Forecaster model. refit : bool, int If the forecaster is refitted during the backtesting process. Returns ------- n_jobs : int The number of jobs to run in parallel. """forecaster_name=type(forecaster).__name__ifisinstance(forecaster.estimator,Pipeline):estimator=forecaster.estimator[-1]estimator_name=type(estimator).__name__else:estimator=forecaster.estimatorestimator_name=type(estimator).__name__linear_estimators=[estimator_nameforestimator_nameindir(sklearn.linear_model)ifnotestimator_name.startswith('_')]refit=Falseifrefit==0elserefitifnotisinstance(refit,bool)andrefit!=1:n_jobs=1else:ifforecaster_namein['ForecasterRecursive']:ifestimator_nameinlinear_estimators:n_jobs=1elifestimator_name=='LGBMRegressor':n_jobs=cpu_count()-1ifestimator.n_jobs==1else1else:n_jobs=cpu_count()-1elifforecaster_namein['ForecasterDirect','ForecasterDirectMultiVariate']:# Parallelization is applied during the fitting process.n_jobs=1elifforecaster_namein['ForecasterRecursiveMultiSeries']:ifestimator_name=='LGBMRegressor':n_jobs=cpu_count()-1ifestimator.n_jobs==1else1else:n_jobs=cpu_count()-1elifforecaster_namein['ForecasterStats','ForecasterEquivalentDate']:n_jobs=1else:n_jobs=1returnn_jobs