Skip to content

[MNT] Regression on forecaster.clone() #536

@CloseChoice

Description

@CloseChoice

Describe the maintenance issue
With the change in this PR, the clone plugins were changed effectively from None (at least in the case I discovered, see script below for reproducibility) to [_PretrainedCloner] see here.

This causes issues with skbase HEAD, but is fixed in skbase main, specifically by this commit 4a79942. As can be seen in that commit, a test was properly added in skbase, nethertheless the dependency of sktime main to skbase main is not clearly stated and rather implicit. If one needs to act upon that is another question or if the implicit knowledge is enough.

Here is the script for reproduction I used:

import numpy as np

import sktime
from sktime.datasets import load_airline
from sktime.forecasting.exp_smoothing import ExponentialSmoothing
from sktime.forecasting.model_evaluation import evaluate
from sktime.performance_metrics.forecasting import MeanAbsolutePercentageError
from sktime.split import ExpandingWindowSplitter
import pandas as pd

y = load_airline()
fh = np.arange(1, 25)

ets = ExponentialSmoothing(trend="add", seasonal="mul", sp=12)
cv = ExpandingWindowSplitter(fh=fh, initial_window=24, step_length=12)

results = evaluate(
    forecaster=ets,
    cv=cv,
    y=y,
    scoring=MeanAbsolutePercentageError(),
    return_data=True,
)

print(results[["test_MeanAbsolutePercentageError", "cutoff"]])

# On main, ExponentialSmoothing fits fail silently (cutoff=NaT),
# so y_pred at split 5 are NA instead of pd.Series.
# This causes plot_series (and any downstream use) to crash.
y_test = results.loc[5, "y_test"]
y_pred = results.loc[5, "y_pred"]


assert isinstance(y_test, pd.Series), f"BUG: y_test should be a pd.Series, got {type(y_test)}: {y_test!r}"
assert isinstance(y_pred, pd.Series), f"BUG: y_pred should be a pd.Series, got {type(y_pred)}: {y_pred!r}"

sktime main + skbase 0.13.1 result in a silent error that cause y_pred to be NA, while with skbase main we get

ipdb> y_test
Period
1956-01    284.0
1956-02    277.0
1956-03    317.0
1956-04    313.0
1956-05    318.0
1956-06    374.0
1956-07    413.0
1956-08    405.0
1956-09    355.0
1956-10    306.0
1956-11    271.0
1956-12    306.0
1957-01    315.0
1957-02    301.0
1957-03    356.0
1957-04    348.0
1957-05    355.0
1957-06    422.0
1957-07    465.0
1957-08    467.0
1957-09    404.0
1957-10    347.0
1957-11    305.0
1957-12    336.0
Freq: M, Name: Number of airline passengers, dtype: float64

Some more details on the incompatibility: there is an error thrown and caught when executing the script, specifically on forecaster.clone(), the error is something like list does not have attribute clone since we append a list to a list resulting in [_PretrainedCloner, [list of other cloners]]. The error is caught and default values assigned subsequently.

cc @SimonBlanke @fkiraly

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions