-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ENH] Created _DelegatedTransformer (#2612)
Related to convo in #2603, simpler alternative to #2570 Creates a `_DelegatedTransformer`. Design and use are identical to `_DelegatedForecaster`.
- Loading branch information
Showing
1 changed file
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
# -*- coding: utf-8 -*- | ||
"""Delegator mixin that delegates all methods to wrapped transformer. | ||
Useful for building estimators where all but one or a few methods are delegated. | ||
For that purpose, inherit from this estimator and then override only the methods | ||
that are not delegated. | ||
""" | ||
# copyright: sktime developers, BSD-3-Clause License (see LICENSE file) | ||
|
||
__author__ = ["miraep8"] | ||
__all__ = ["_DelegatedTransformer"] | ||
|
||
from sktime.transformations.base import BaseTransformer | ||
|
||
|
||
class _DelegatedTransformer(BaseTransformer): | ||
"""Delegator mixin that delegates all methods to wrapped transformer. | ||
Delegates inner transformer methods to a wrapped estimator. | ||
Wrapped estimator is value of attribute with name self._delegate_name. | ||
By default, this is "estimator_", i.e., delegates to self.estimator_ | ||
To override delegation, override _delegate_name attribute in child class. | ||
Delegates the following inner underscore methods: | ||
_fit, _transform, _inverse_transform, _update | ||
Does NOT delegate get_params, set_params. | ||
get_params, set_params will hence use one additional nesting level by default. | ||
Does NOT delegate or copy tags, this should be done in a child class if required. | ||
""" | ||
|
||
_delegate_name = "estimator_" | ||
|
||
def _get_delegate(self): | ||
return getattr(self, self._delegate_name) | ||
|
||
def _fit(self, X, y=None): | ||
"""Fit wrapped transformer to X, optionally to y. | ||
Parameters | ||
---------- | ||
X : Series or Panel, any supported mtype | ||
Data to fit transform to, of python type as follows: | ||
Series: pd.Series, pd.DataFrame, or np.ndarray (1D or 2D) | ||
Panel: pd.DataFrame with 2-level MultiIndex, list of pd.DataFrame, | ||
nested pd.DataFrame, or pd.DataFrame in long/wide format | ||
subject to sktime mtype format specifications, for further details see | ||
examples/AA_datatypes_and_datasets.ipynb | ||
y : Series or Panel, default=None | ||
Additional data, e.g., labels for transformation | ||
Returns | ||
------- | ||
self : a fitted instance of the estimator | ||
""" | ||
estimator = self._get_delegate() | ||
estimator.fit(X=X, y=y) | ||
return self | ||
|
||
def _transform(self, X, y=None): | ||
"""Use wrapped transformer to transform X and return a transformed version. | ||
Parameters | ||
---------- | ||
X : Series or Panel, any supported mtype | ||
Data to be transformed, of python type as follows: | ||
Series: pd.Series, pd.DataFrame, or np.ndarray (1D or 2D) | ||
Panel: pd.DataFrame with 2-level MultiIndex, list of pd.DataFrame, | ||
nested pd.DataFrame, or pd.DataFrame in long/wide format | ||
subject to sktime mtype format specifications, for further details see | ||
examples/AA_datatypes_and_datasets.ipynb | ||
y : Series or Panel, default=None | ||
Additional data, e.g., labels for transformation | ||
Returns | ||
------- | ||
transformed version of X | ||
type depends on type of X and scitype:transform-output tag: | ||
| | `transform` | | | ||
| `X` | `-output` | type of return | | ||
|----------|--------------|------------------------| | ||
| `Series` | `Primitives` | `pd.DataFrame` (1-row) | | ||
| `Panel` | `Primitives` | `pd.DataFrame` | | ||
| `Series` | `Series` | `Series` | | ||
| `Panel` | `Series` | `Panel` | | ||
| `Series` | `Panel` | `Panel` | | ||
instances in return correspond to instances in `X` | ||
combinations not in the table are currently not supported | ||
Explicitly, with examples: | ||
if `X` is `Series` (e.g., `pd.DataFrame`) and `transform-output` is `Series` | ||
then the return is a single `Series` of the same mtype | ||
Example: detrending a single series | ||
if `X` is `Panel` (e.g., `pd-multiindex`) and `transform-output` is `Series` | ||
then the return is `Panel` with same number of instances as `X` | ||
(the transformer is applied to each input Series instance) | ||
Example: all series in the panel are detrended individually | ||
if `X` is `Series` or `Panel` and `transform-output` is `Primitives` | ||
then the return is `pd.DataFrame` with as many rows as instances in `X` | ||
Example: i-th row of the return has mean and variance of the i-th series | ||
if `X` is `Series` and `transform-output` is `Panel` | ||
then the return is a `Panel` object of type `pd-multiindex` | ||
Example: i-th instance of the output is the i-th window running over `X` | ||
""" | ||
estimator = self._get_delegate() | ||
return estimator.transform(X, y=y) | ||
|
||
def _inverse_transform(self, X, y=None): | ||
"""Use wrapped transformer to inverse transform X and return. | ||
Currently it is assumed that only transformers with tags | ||
"scitype:transform-input"="Series", "scitype:transform-output"="Series", | ||
have an inverse_transform. | ||
Parameters | ||
---------- | ||
X : Series or Panel, any supported mtype | ||
Data to be inverse transformed, of python type as follows: | ||
Series: pd.Series, pd.DataFrame, or np.ndarray (1D or 2D) | ||
Panel: pd.DataFrame with 2-level MultiIndex, list of pd.DataFrame, | ||
nested pd.DataFrame, or pd.DataFrame in long/wide format | ||
subject to sktime mtype format specifications, for further details see | ||
examples/AA_datatypes_and_datasets.ipynb | ||
y : Series or Panel, default=None | ||
Additional data, e.g., labels for transformation | ||
Returns | ||
------- | ||
inverse transformed version of X | ||
of the same type as X, and conforming to mtype format specifications | ||
""" | ||
estimator = self._get_delegate() | ||
return estimator.inverse_transform(X=X, y=y) | ||
|
||
def _update(self, X, y=None, update_params=True): | ||
"""Update wrapped transformer with X, optionally y. | ||
State required: | ||
Requires state to be "fitted". | ||
Writes to self: | ||
May update fitted model attributes ending in for the delegated | ||
transformer "_" via update. | ||
Parameters | ||
---------- | ||
X : Series or Panel, any supported mtype | ||
Data to fit transform to, of python type as follows: | ||
Series: pd.Series, pd.DataFrame, or np.ndarray (1D or 2D) | ||
Panel: pd.DataFrame with 2-level MultiIndex, list of pd.DataFrame, | ||
nested pd.DataFrame, or pd.DataFrame in long/wide format | ||
subject to sktime mtype format specifications, for further details see | ||
examples/AA_datatypes_and_datasets.ipynb | ||
y : Series or Panel, default=None | ||
Additional data, e.g., labels for transformation | ||
update_params : bool, default=True | ||
whether the model is updated. Yes if true, if false, simply skips call. | ||
argument exists for compatibility with forecasting module. | ||
Returns | ||
------- | ||
self : a fitted instance of the estimator | ||
""" | ||
estimator = self._get_delegate() | ||
estimator.update(y=y, X=X, update_params=update_params) | ||
return self |