sktime.benchmarking.strategies 源代码

"""Unified high-level interface for various time series related learning strategies."""

__all__ = ["TSCStrategy", "TSRStrategy"]
__author__ = ["mloning", "sajaysurya"]

import pandas as pd
from joblib import dump, load
from sklearn.base import ClassifierMixin, RegressorMixin
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
from sklearn.pipeline import Pipeline

from sktime.base import BaseEstimator
from sktime.classification.base import BaseClassifier
from sktime.forecasting.base._sktime import BaseForecaster
from sktime.regression.base import BaseRegressor

# TODO implement task-strategy-estimator compatibility lookup registry using
#  strategy traits
REGRESSOR_TYPES = (BaseRegressor, RegressorMixin)
CLASSIFIER_TYPES = (BaseClassifier, ClassifierMixin)
FORECASTER_TYPES = (BaseForecaster,)
ESTIMATOR_TYPES = REGRESSOR_TYPES + CLASSIFIER_TYPES + FORECASTER_TYPES

CASES = ("TSR", "TSC")


[文档]class BaseStrategy(BaseEstimator): """Abstract base strategy class. Implements attributes and operations shared by all strategies, including input and compatibility checks between passed estimator, data and task. """ def __init__(self, estimator, name=None): self._check_estimator_compatibility(estimator) self._estimator = estimator self._name = estimator.__class__.__name__ if name is None else name self._task = None @property def name(self): """Read-only name attribute.""" return self._name @property def estimator(self): """Read-only estimator attribute.""" return self._estimator def __getitem__(self, key): """Provide read only access via keys to the private traits.""" if key not in self._traits.keys(): raise KeyError return self._traits[key]
[文档] def fit(self, task, data): """Fit the strategy to the given task and data. Parameters ---------- task : Task Task encapsulating metadata information on feature and target variables to which to fit the data to. data : pandas.DataFrame Dataframe with feature and target variables as specified in task. Returns ------- self : an instance of the self """ self._validate_data(data) # Check task compatibility with strategy self._check_task_compatibility(task) self._task = task # Set metadata if not already set if self._task.metadata is None: self._task.set_metadata(data) # strategy-specific implementation return self._fit(data)
def _check_task_compatibility(self, task): """Check compatibility of task with strategy.""" # TODO replace by task-strategy compatibility lookup registry if hasattr(task, "_case"): if self._case != task._case: raise ValueError( "Strategy <-> task mismatch: The chosen strategy is " "incompatible with the given task" ) else: raise AttributeError("The passed case of the task is unknown") def _check_estimator_compatibility(self, estimator): """Check compatibility of estimator with strategy.""" # Determine required estimator type from strategy case # TODO replace with strategy - estimator type registry lookup if hasattr(self, "_traits"): required = self._traits["required_estimator_type"] if any( estimator_type not in ESTIMATOR_TYPES for estimator_type in required ): raise AttributeError("Required estimator type unknown") else: raise AttributeError("Required estimator type not found") # # Check estimator compatibility with required type # If pipeline, check compatibility of final estimator if isinstance(estimator, Pipeline): final_estimator = estimator.steps[-1][1] if not isinstance(final_estimator, required): raise ValueError( f"Final estimator of passed pipeline estimator must be " f"of type: {required}, " f"but found: {type(final_estimator)}" ) # If tuning meta-estimator, check compatibility of inner estimator elif isinstance(estimator, (GridSearchCV, RandomizedSearchCV)): estimator = estimator.estimator if not isinstance(estimator, required): raise ValueError( f"Inner estimator of passed meta-estimator must be of " f"type: {required}, " f"but found: {type(estimator)}" ) # Otherwise check estimator directly else: if not isinstance(estimator, required): raise ValueError( f"Passed estimator has to be of type: {required}, " f"but found: {type(estimator)}" ) @staticmethod def _validate_data(data): """Validate input data.""" if not isinstance(data, pd.DataFrame): raise ValueError(f"Data must be pandas DataFrame, but found: {type(data)}") # TODO add input checks for contents, ie all cells be pandas Series, # numpy arrays or primitives, # ultimately move checks to data container # s = y.iloc[0] # if not isinstance(s, (np.ndarray, pd.Series)): # raise ValueError(f'``y`` must contain a pandas Series or numpy # array, but found: {type(s)}.')
[文档] def save(self, path): dump(self, path)
[文档] def load(self, path): """Load saved strategy. Parameters ---------- path: String location on disk where the strategy was saved Returns ------- strategy: sktime strategy """ return load(path)
def __repr__(self): strategy_name = self.__class__.__name__ estimator_name = self.estimator.__class__.__name__ return f"{strategy_name}({estimator_name}({repr(self.get_params(deep=False))}))"
[文档]class BaseSupervisedLearningStrategy(BaseStrategy): """Abstract strategy class for time series supervised learning. Accepts a low-level estimator to perform a given task. Implements predict and internal fit methods for time series regression and classification. """ def _fit(self, data): """Fit estimator - inner logic. Parameters ---------- data : pandas.DataFrame Dataframe with feature and target variables as specified in task. Returns ------- self : an instance of self """ # select features and target X = data[self._task.features] y = data[self._task.target] # fit the estimator return self.estimator.fit(X, y)
[文档] def predict(self, data): """Predict using the given test data. Parameters ---------- data : a pandas.DataFrame Dataframe with feature and target variables as specified in task passed to ``fit``. Returns ------- y_pred : pandas.Series Returns the series of predicted values. """ # select features X = data[self._task.features] # predict return self.estimator.predict(X)
[文档]class TSCStrategy(BaseSupervisedLearningStrategy): """Strategy for time series classification. Parameters ---------- estimator : an estimator Low-level estimator used in strategy. name : str, optional (default=None) Name of strategy. If None, class name of estimator is used. """ def __init__(self, estimator, name=None): self._case = "TSC" self._traits = {"required_estimator_type": CLASSIFIER_TYPES} super().__init__(estimator, name=name)
[文档]class TSRStrategy(BaseSupervisedLearningStrategy): """Strategy for time series regression. Parameters ---------- estimator : an estimator Low-level estimator used in strategy. name : str, optional (default=None) Name of strategy. If None, class name of estimator is used. """ def __init__(self, estimator, name=None): self._case = "TSR" self._traits = {"required_estimator_type": REGRESSOR_TYPES} super().__init__(estimator, name=name)