Skip to content

Commit

Permalink
[MNT] 0.27.0 deprecations and change actions (#5974)
Browse files Browse the repository at this point in the history
Carries out deprecations and change actions scheduled for 0.26.0:

* finish renaming of `PAA2` to `PAA` , `SAX2` to `SAX`
* remove `remember_data` arg from `SplitterSummarizer`
* remove `n_jobs`, `pre_dispatch` parameters in forecasting tuners
* bump deprecation/change checks scheduled for 0.27.0 to 0.28.0
  • Loading branch information
fkiraly authored Feb 27, 2024
1 parent d31dfd9 commit 089d9f1
Show file tree
Hide file tree
Showing 18 changed files with 65 additions and 148 deletions.
4 changes: 2 additions & 2 deletions examples/01_forecasting.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -6544,7 +6544,7 @@
" \"scaler__passthrough\": [True, False],\n",
" \"forecaster__strategy\": [\"drift\", \"mean\", \"last\"],\n",
"}\n",
"gscv = ForecastingGridSearchCV(forecaster=pipe, param_grid=param_grid, cv=cv, n_jobs=-1)"
"gscv = ForecastingGridSearchCV(forecaster=pipe, param_grid=param_grid, cv=cv)"
]
},
{
Expand Down Expand Up @@ -6817,7 +6817,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.11"
"version": "3.11.5"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
Expand Down
8 changes: 0 additions & 8 deletions examples/03b_forecasting_transformers_pipelines_tuning.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,6 @@
" forecaster=forecaster,\n",
" param_grid=param_grid,\n",
" cv=cv,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
" scoring=MeanSquaredError(square_root=True),\n",
")\n",
Expand Down Expand Up @@ -855,7 +854,6 @@
" forecaster=forecaster,\n",
" param_grid=param_grid,\n",
" cv=cv,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
" scoring=MeanSquaredError(square_root=True), # set custom scoring function\n",
")\n",
Expand Down Expand Up @@ -959,7 +957,6 @@
" },\n",
" ],\n",
" cv=cv,\n",
" n_jobs=-1,\n",
")\n",
"gscv.fit(y)\n",
"gscv.best_params_"
Expand Down Expand Up @@ -1003,7 +1000,6 @@
" forecaster=forecaster,\n",
" param_grid={\"selected_forecaster\": [\"naive\", \"stl\", \"theta\"]},\n",
" cv=cv,\n",
" n_jobs=-1,\n",
")\n",
"gscv.fit(y)\n",
"gscv.best_params_"
Expand Down Expand Up @@ -1305,7 +1301,6 @@
" forecaster=forecaster,\n",
" param_grid=param_grid,\n",
" cv=cv,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
" scoring=MeanSquaredError(square_root=True),\n",
")\n",
Expand Down Expand Up @@ -1431,7 +1426,6 @@
" forecaster=permuted,\n",
" param_grid=param_grid,\n",
" cv=cv,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
" scoring=MeanSquaredError(square_root=True),\n",
")\n",
Expand Down Expand Up @@ -1742,7 +1736,6 @@
" forecaster=permuted_y,\n",
" param_grid=param_grid,\n",
" cv=cv,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
" scoring=MeanSquaredError(square_root=True),\n",
" error_score=\"raise\",\n",
Expand Down Expand Up @@ -2266,7 +2259,6 @@
" cv=cv,\n",
" error_score=\"raise\",\n",
" scoring=MeanSquaredError(square_root=True),\n",
" n_jobs=-1,\n",
")\n",
"\n",
"gscv.fit(y=y_train, X=X_train)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from sktime.utils.validation.panel import check_X


# TODO: fix this in 0.27.0
# TODO: fix this in 0.28.0
# base class should have been changed to BaseEarlyClassifier
class ProbabilityThresholdEarlyClassifier(BaseClassifier):
"""Probability Threshold Early Classifier.
Expand Down
2 changes: 1 addition & 1 deletion sktime/forecasting/base/_fh.py
Original file line number Diff line number Diff line change
Expand Up @@ -809,7 +809,7 @@ def _to_relative(fh: ForecastingHorizon, cutoff=None) -> ForecastingHorizon:
absolute = _coerce_to_period(absolute, freq=fh.freq)
cutoff = _coerce_to_period(cutoff, freq=fh.freq)

# TODO: 0.27.0:
# TODO: 0.28.0:
# Check at every minor release whether lower pandas bound >=0.15.0
# if yes, can remove the workaround in the "else" condition and the check
#
Expand Down
2 changes: 1 addition & 1 deletion sktime/forecasting/compose/_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def _get_inverse_transform(self, transformers, y, X=None, mode=None):
if len(levels) == 1:
levels = levels[0]
yt[ix] = y.xs(ix, level=levels, axis=1)
# todo 0.27.0 - check why this cannot be easily removed
# todo 0.28.0 - check why this cannot be easily removed
# in theory, we should get rid of the "Coverage" case treatment
# (the legacy naming convention was removed in 0.23.0)
# deal with the "Coverage" case, we need to get rid of this
Expand Down
6 changes: 3 additions & 3 deletions sktime/forecasting/model_selection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
)


# todo 0.27.0 - check whether we should remove, otherwise bump
# todo 0.28.0 - check whether we should remove, otherwise bump
# still used in blog posts and old tutorials
def temporal_train_test_split(
y, X=None, test_size=None, train_size=None, fh=None, anchor="start"
Expand All @@ -45,7 +45,7 @@ def temporal_train_test_split(
)


# todo 0.27.0 - check whether we should remove, otherwise bump
# todo 0.28.0 - check whether we should remove, otherwise bump
# still used in blog posts and old tutorials
def ExpandingWindowSplitter(fh=1, initial_window=10, step_length=1):
"""Legacy export of Expanding window splitter.
Expand All @@ -68,7 +68,7 @@ def ExpandingWindowSplitter(fh=1, initial_window=10, step_length=1):
return _EWSplitter(fh=fh, initial_window=initial_window, step_length=step_length)


# todo 0.27.0 - check whether we should remove, otherwise bump
# todo 0.28.0 - check whether we should remove, otherwise bump
# still used in blog posts and old tutorials
def SlidingWindowSplitter(
fh=1, window_length=10, step_length=1, initial_window=None, start_with_window=True
Expand Down
71 changes: 21 additions & 50 deletions sktime/forecasting/model_selection/_tune.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,11 @@ class BaseGridSearch(_DelegatedForecaster):
"capability:pred_int:insample": True,
}

# todo 0.27.0: remove n_jobs, pre_dispatch parameters and all related logic
def __init__(
self,
forecaster,
cv,
strategy="refit",
n_jobs=None,
pre_dispatch=None,
backend="loky",
refit=False,
scoring=None,
Expand All @@ -56,12 +53,11 @@ def __init__(
tune_by_instance=False,
tune_by_variable=False,
backend_params=None,
n_jobs="deprecated",
):
self.forecaster = forecaster
self.cv = cv
self.strategy = strategy
self.n_jobs = n_jobs
self.pre_dispatch = pre_dispatch
self.backend = backend
self.refit = refit
self.scoring = scoring
Expand All @@ -72,6 +68,7 @@ def __init__(
self.tune_by_instance = tune_by_instance
self.tune_by_variable = tune_by_variable
self.backend_params = backend_params
self.n_jobs = n_jobs

super().__init__()

Expand All @@ -87,6 +84,18 @@ def __init__(
if tune_by_variable:
self.set_tags(**{"scitype:y": "univariate"})

# todo 0.28.0: check if this is still necessary
# n_jobs is deprecated, left due to use in tutorials, books, blog posts
if n_jobs != "deprecated":
warn(
f"Parameter n_jobs of {self.__class__.__name__} has been removed "
"in sktime 0.27.0 and is no longer used. It is ignored when passed. "
"Instead, the backend and backend_params parameters should be used "
"to pass n_jobs or other parallelization parameters.",
obj=self,
stacklevel=2,
)

# attribute for _DelegatedForecaster, which then delegates
# all non-overridden methods are same as of getattr(self, _delegate_name)
# see further details in _DelegatedForecaster docstring
Expand Down Expand Up @@ -177,25 +186,8 @@ def _fit(self, y, X, fh):
scoring = check_scoring(self.scoring, obj=self)
scoring_name = f"test_{scoring.name}"

# todo 0.27.0: remove this logic and only use backend_params
backend = self.backend
backend_params = self.backend_params if self.backend_params else {}
if backend in ["threading", "multiprocessing", "loky"]:
n_jobs = self.n_jobs
pre_dispatch = self.pre_dispatch
if n_jobs is not None:
backend_params["n_jobs"] = n_jobs
if pre_dispatch is not None:
backend_params["pre_dispatch"] = pre_dispatch
if n_jobs is not None or pre_dispatch is not None:
warn(
f"in {self.__class__.__name__}, n_jobs and pre_dispatch "
"parameters are deprecated and will be removed in 0.27.0. "
"Please use n_jobs and pre_dispatch directly in the backend_params "
"argument instead.",
obj=self,
stacklevel=2,
)

def evaluate_candidates(candidate_params):
candidate_params = list(candidate_params)
Expand Down Expand Up @@ -445,10 +437,6 @@ class ForecastingGridSearchCV(BaseGridSearch):
* If None, defaults to MeanAbsolutePercentageError()
n_jobs: int, optional (default=None)
Number of jobs to run in parallel.
None means 1 unless in a joblib.parallel_backend context.
-1 means using all processors.
refit : bool, optional (default=True)
True = refit the forecaster with the best parameters on the entire data in fit
False = no refitting takes place. The forecaster cannot be used to predict.
Expand All @@ -458,7 +446,6 @@ class ForecastingGridSearchCV(BaseGridSearch):
return_n_best_forecasters : int, default=1
In case the n best forecaster should be returned, this value can be set
and the n best forecasters will be assigned to n_best_forecasters_
pre_dispatch : str, optional (default='2*n_jobs')
error_score : numeric value or the str 'raise', optional (default=np.nan)
The test score returned when a forecaster fails to be fitted.
return_train_score : bool, optional (default=False)
Expand Down Expand Up @@ -599,7 +586,7 @@ class ForecastingGridSearchCV(BaseGridSearch):
... },
... ],
... cv=cv,
... n_jobs=-1) # doctest: +SKIP
... ) # doctest: +SKIP
>>> gscv.fit(y) # doctest: +SKIP
ForecastingGridSearchCV(...)
>>> y_pred = gscv.predict(fh=[1,2,3]) # doctest: +SKIP
Expand All @@ -612,34 +599,32 @@ def __init__(
param_grid,
scoring=None,
strategy="refit",
n_jobs=None,
refit=True,
verbose=0,
return_n_best_forecasters=1,
pre_dispatch="2*n_jobs",
backend="loky",
update_behaviour="full_refit",
error_score=np.nan,
tune_by_instance=False,
tune_by_variable=False,
backend_params=None,
n_jobs="deprecated",
):
super().__init__(
forecaster=forecaster,
scoring=scoring,
n_jobs=n_jobs,
refit=refit,
cv=cv,
strategy=strategy,
verbose=verbose,
return_n_best_forecasters=return_n_best_forecasters,
pre_dispatch=pre_dispatch,
backend=backend,
update_behaviour=update_behaviour,
error_score=error_score,
tune_by_instance=tune_by_instance,
tune_by_variable=tune_by_variable,
backend_params=backend_params,
n_jobs=n_jobs,
)
self.param_grid = param_grid

Expand Down Expand Up @@ -780,10 +765,6 @@ class ForecastingRandomizedSearchCV(BaseGridSearch):
* If None, defaults to MeanAbsolutePercentageError()
n_jobs : int, optional (default=None)
Number of jobs to run in parallel.
None means 1 unless in a joblib.parallel_backend context.
-1 means using all processors.
refit : bool, optional (default=True)
True = refit the forecaster with the best parameters on the entire data in fit
False = no refitting takes place. The forecaster cannot be used to predict.
Expand All @@ -798,7 +779,6 @@ class ForecastingRandomizedSearchCV(BaseGridSearch):
from lists of possible values instead of scipy.stats distributions.
Pass an int for reproducible output across multiple
function calls.
pre_dispatch : str, optional (default='2*n_jobs')
backend : {"dask", "loky", "multiprocessing", "threading"}, by default "loky".
Runs parallel evaluate if specified and `strategy` is set as "refit".
Expand Down Expand Up @@ -884,35 +864,33 @@ def __init__(
n_iter=10,
scoring=None,
strategy="refit",
n_jobs=None,
refit=True,
verbose=0,
return_n_best_forecasters=1,
random_state=None,
pre_dispatch="2*n_jobs",
backend="loky",
update_behaviour="full_refit",
error_score=np.nan,
tune_by_instance=False,
tune_by_variable=False,
backend_params=None,
n_jobs="deprecated",
):
super().__init__(
forecaster=forecaster,
scoring=scoring,
strategy=strategy,
n_jobs=n_jobs,
refit=refit,
cv=cv,
verbose=verbose,
return_n_best_forecasters=return_n_best_forecasters,
pre_dispatch=pre_dispatch,
backend=backend,
update_behaviour=update_behaviour,
error_score=error_score,
tune_by_instance=tune_by_instance,
tune_by_variable=tune_by_variable,
backend_params=backend_params,
n_jobs=n_jobs,
)
self.param_distributions = param_distributions
self.n_iter = n_iter
Expand Down Expand Up @@ -1060,11 +1038,6 @@ class ForecastingSkoptSearchCV(BaseGridSearch):
return_n_best_forecasters: int, default=1
In case the n best forecaster should be returned, this value can be set
and the n best forecasters will be assigned to n_best_forecasters_
pre_dispatch : str, optional (default='2*n_jobs')
n_jobs : int, optional (default=None)
Number of jobs to run in parallel.
None means 1 unless in a joblib.parallel_backend context.
-1 means using all processors.
backend : {"dask", "loky", "multiprocessing", "threading"}, by default "loky".
Runs parallel evaluate if specified and `strategy` is set as "refit".
Expand Down Expand Up @@ -1188,17 +1161,16 @@ def __init__(
scoring: Optional[List[BaseMetric]] = None,
optimizer_kwargs: Optional[Dict] = None,
strategy: Optional[str] = "refit",
n_jobs: Optional[int] = None,
refit: bool = True,
verbose: int = 0,
return_n_best_forecasters: int = 1,
pre_dispatch: str = "2*n_jobs",
backend: str = "loky",
update_behaviour: str = "full_refit",
error_score=np.nan,
tune_by_instance=False,
tune_by_variable=False,
backend_params=None,
n_jobs="deprecated",
):
self.param_distributions = param_distributions
self.n_iter = n_iter
Expand All @@ -1209,18 +1181,17 @@ def __init__(
forecaster=forecaster,
scoring=scoring,
strategy=strategy,
n_jobs=n_jobs,
refit=refit,
cv=cv,
verbose=verbose,
return_n_best_forecasters=return_n_best_forecasters,
pre_dispatch=pre_dispatch,
backend=backend,
update_behaviour=update_behaviour,
error_score=error_score,
tune_by_instance=tune_by_instance,
tune_by_variable=tune_by_variable,
backend_params=backend_params,
n_jobs=n_jobs,
)

def _fit(self, y, X=None, fh=None):
Expand Down
Loading

0 comments on commit 089d9f1

Please sign in to comment.