Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Refactoring and Generalizing DelegatedForecaster #2570

Closed
wants to merge 70 commits into from
Closed
Show file tree
Hide file tree
Changes from 52 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
13448fe
multiplexer using delegate
fkiraly Apr 13, 2022
4153cb6
improved docstring
fkiraly Apr 13, 2022
f726e79
use heterogeneousensemble methods
fkiraly Apr 13, 2022
8f04e33
docstring
fkiraly Apr 13, 2022
e016493
fixed clone ref, added None param
fkiraly Apr 13, 2022
44b77c5
removing EnsembleForecaster parent
fkiraly Apr 13, 2022
93911ac
multiplexer fit is not empty
fkiraly Apr 13, 2022
1f3be57
refactor update_predict
fkiraly Apr 14, 2022
45c4125
Merge branch 'update_predict_first_refactor' into multiplexer-proba
fkiraly Apr 14, 2022
4d38642
Merge branch 'main' into multiplexer-proba
fkiraly Apr 14, 2022
1c69be4
Add tests for multiplex.py
miraep8 Apr 21, 2022
3efce72
remove part of multiplex.py test that depends on changes I made
miraep8 Apr 21, 2022
3a2c297
Merge branch 'main' into multiplex_additions
miraep8 Apr 21, 2022
44a9868
Added test for MultiplexForecaster alone
miraep8 Apr 21, 2022
79ccd70
Merge branch 'main' into multiplex_additions
miraep8 Apr 21, 2022
346a51d
Changing author and ensuring clone then copy
miraep8 Apr 21, 2022
d8ee716
Merge branch 'main' into multiplexer-proba
fkiraly Apr 21, 2022
849ac5c
fixed bug found by miraep8 test suite
fkiraly Apr 22, 2022
0db3b71
Merge branch 'main' into multiplexer-proba
fkiraly Apr 22, 2022
8e5036d
Merge branch 'alan-turing-institute:main' into multiplex_additions
miraep8 Apr 23, 2022
a7ee8e7
Added | dunder and tests to MultiplexForecaster
miraep8 Apr 23, 2022
72fc843
Fixing some of Franz's suggestions
miraep8 Apr 23, 2022
85cfb36
Merge branch 'multiplexer-proba' into multiplex_additions
miraep8 Apr 23, 2022
32ef9cd
changing MultiplexForecaster __or__ to return NotImplemented instead …
miraep8 Apr 23, 2022
6ba07f8
ValueError -> TypeError
miraep8 Apr 23, 2022
d48030e
Merge branch 'main' into multiplex_additions
miraep8 Apr 24, 2022
773bb88
Merge branch 'main' into multiplex_additions
miraep8 Apr 24, 2022
fc6309c
Merge branch 'main' into multiplex_additions
miraep8 Apr 24, 2022
9356066
Merge branch 'main' into multiplex_additions
miraep8 Apr 25, 2022
cfd1d20
Merge branch 'main' into multiplex_additions
miraep8 Apr 25, 2022
c0006c1
Merge branch 'main' into multiplex_additions
miraep8 Apr 26, 2022
1e5a598
Merge branch 'main' into multiplex_additions
fkiraly Apr 27, 2022
68e1117
Merge branch 'main' into multiplex_additions
miraep8 Apr 27, 2022
e4cd2cd
Merge branch 'alan-turing-institute:main' into general_delegator
miraep8 Apr 28, 2022
a8f99c7
refactoring delegator
miraep8 Apr 28, 2022
d9409ef
Merge branch 'general_delegator' of https://github.com/miraep8/sktime…
miraep8 Apr 28, 2022
f8f344d
Merge branch 'alan-turing-institute:main' into general_delegator
miraep8 Apr 28, 2022
0cb3606
name change and adding tag cloning
miraep8 Apr 28, 2022
302911b
Hopefully fix
miraep8 Apr 28, 2022
d0a5557
adding delegation to GridForecastCV
miraep8 Apr 28, 2022
88a8aa7
Merge branch 'main' into general_delegator
miraep8 Apr 28, 2022
0b42a80
bug ressolutions
miraep8 Apr 28, 2022
f624157
Merge branch 'main' into general_delegator
miraep8 Apr 28, 2022
b242c56
inconsequential change
miraep8 Apr 28, 2022
b2c4c89
remove inconseqeuntial change
miraep8 Apr 28, 2022
6c15c86
linitng
miraep8 Apr 28, 2022
9897d60
Merge branch 'main' into general_delegator
miraep8 Apr 28, 2022
02cfe77
fixed more of the bugs
miraep8 Apr 28, 2022
c64c6fb
fixing accidental infinite loop
miraep8 Apr 29, 2022
37baf16
More fixes
miraep8 Apr 29, 2022
8e3a9b2
removing the hacky (and broken) workarounds
miraep8 Apr 29, 2022
f0d7173
Merge branch 'main' into general_delegator
miraep8 Apr 30, 2022
71fd2b3
some
miraep8 May 1, 2022
240f905
Merge branch 'general_delegator' of https://github.com/miraep8/sktime…
miraep8 May 1, 2022
a8bcc4a
moving to BaseEstimator
miraep8 May 1, 2022
4f5fb11
implementing suggestions/ci test fix
miraep8 May 1, 2022
aa84965
stop delegating grid search fit
miraep8 May 1, 2022
12c1021
hot fix
miraep8 May 1, 2022
7054289
removing redundency
miraep8 May 1, 2022
976ab62
remove debug changes to test_all_estimators
miraep8 May 1, 2022
61c2ed7
comment change
miraep8 May 1, 2022
1fc49b4
removing final change to test_all_estimators
miraep8 May 1, 2022
a49b3ae
remove final change to test_multiplexer.py
miraep8 May 1, 2022
e74a049
Merge branch 'main' into general_delegator
miraep8 May 1, 2022
9d1c31e
making attributes to copy easier to change
miraep8 May 1, 2022
364bd20
moving attribute out of __init__
miraep8 May 1, 2022
642b6e4
Merge branch 'main' into general_delegator
miraep8 May 1, 2022
bba64f0
test without make_mock_estimator test
miraep8 May 2, 2022
672e4d9
Merge branch 'main' into general_delegator
miraep8 May 2, 2022
353d8ae
Merge branch 'main' into general_delegator
miraep8 May 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions sktime/base/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class name: BaseEstimator
from sklearn.ensemble._base import _set_random_states

from sktime.exceptions import NotFittedError
from sktime.utils.estimator_checks import delegate_if_needed


class BaseObject(_BaseEstimator):
Expand All @@ -68,6 +69,14 @@ class BaseObject(_BaseEstimator):
Extends scikit-learn's BaseEstimator to include sktime interface for tags.
"""

_delegate_name = None

def _get_delegate(self):
est = self
while est._delegate_name:
est = getattr(est, est._delegate_name)
return est

def __init__(self):
self._tags_dynamic = dict()
super(BaseObject, self).__init__()
Expand Down Expand Up @@ -634,10 +643,12 @@ def __init__(self):
super(BaseEstimator, self).__init__()

@property
@delegate_if_needed
def is_fitted(self):
"""Whether `fit` has been called."""
return self._is_fitted

@delegate_if_needed
def check_is_fitted(self):
"""Check if the estimator has been fitted.

Expand Down
21 changes: 21 additions & 0 deletions sktime/forecasting/base/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class name: BaseForecaster
)
from sktime.forecasting.base import ForecastingHorizon
from sktime.utils.datetime import _shift
from sktime.utils.estimator_checks import delegate_if_needed
from sktime.utils.validation._dependencies import _check_dl_dependencies
from sktime.utils.validation.forecasting import check_alpha, check_cv, check_fh, check_X
from sktime.utils.validation.series import check_equal_time_index
Expand Down Expand Up @@ -191,6 +192,7 @@ def __or__(self, other):
else:
return NotImplemented

@delegate_if_needed
def fit(self, y, X=None, fh=None):
"""Fit forecaster to training data.

Expand Down Expand Up @@ -271,6 +273,7 @@ def fit(self, y, X=None, fh=None):

return self

@delegate_if_needed
def predict(
self,
fh=None,
Expand Down Expand Up @@ -331,6 +334,7 @@ def predict(

return y_out

@delegate_if_needed
def fit_predict(self, y, X=None, fh=None):
"""Fit and forecast time series at future horizon.

Expand Down Expand Up @@ -408,6 +412,7 @@ def fit_predict(self, y, X=None, fh=None):
# input conversions are skipped since we are using X_inner
return self.predict(fh=fh, X=X_inner)

@delegate_if_needed
def predict_quantiles(self, fh=None, X=None, alpha=None):
"""Compute/return quantile forecasts.

Expand Down Expand Up @@ -479,6 +484,7 @@ def predict_quantiles(self, fh=None, X=None, alpha=None):

return quantiles

@delegate_if_needed
def predict_interval(
self,
fh=None,
Expand Down Expand Up @@ -556,6 +562,7 @@ def predict_interval(

return pred_int

@delegate_if_needed
def predict_var(self, fh=None, X=None, cov=False):
"""Compute/return variance forecasts.

Expand Down Expand Up @@ -626,6 +633,7 @@ def predict_var(self, fh=None, X=None, cov=False):

return pred_var

@delegate_if_needed
def predict_proba(self, fh=None, X=None, marginal=True):
"""Compute/return fully probabilistic forecasts.

Expand Down Expand Up @@ -691,6 +699,7 @@ def predict_proba(self, fh=None, X=None, marginal=True):

return pred_dist

@delegate_if_needed
def update(self, y, X=None, update_params=True):
"""Update cutoff value and, optionally, fitted parameters.

Expand Down Expand Up @@ -765,6 +774,7 @@ def update(self, y, X=None, update_params=True):

return self

@delegate_if_needed
def update_predict(
self,
y,
Expand Down Expand Up @@ -851,6 +861,7 @@ def update_predict(
reset_forecaster=reset_forecaster,
)

@delegate_if_needed
def update_predict_single(
self,
y=None,
Expand Down Expand Up @@ -939,6 +950,7 @@ def update_predict_single(
update_params=update_params,
)

@delegate_if_needed
def predict_residuals(self, y=None, X=None):
"""Return residuals of time series forecasts.

Expand Down Expand Up @@ -1013,6 +1025,7 @@ def predict_residuals(self, y=None, X=None):

return y_res

@delegate_if_needed
def score(self, y, X=None, fh=None):
"""Scores forecast against ground truth, using MAPE.

Expand Down Expand Up @@ -1377,6 +1390,7 @@ def _get_y_pred(self, y_in_sample, y_out_sample):
return y_pred

@property
@delegate_if_needed
def cutoff(self):
"""Cut-off = "present time" state of forecaster.

Expand Down Expand Up @@ -1417,6 +1431,13 @@ def _set_cutoff_from_y(self, y):
self._cutoff = cutoff_idx

@property
@delegate_if_needed
def y(self):
"""Return y that was passed."""
return self._y

@property
@delegate_if_needed
def fh(self):
"""Forecasting horizon that was passed."""
# raise error if some method tries to accessed it before it has been set
Expand Down
Loading