Skip to content

Scitype interface specification: forecaster

Franz Király edited this page Jun 18, 2021 · 15 revisions

WARNING: this is outdated, interface has been refactored since - refer to sphinx docs and current extension templates

Scitype interface specification: forecaster

Quick extension reference

This section contains a copy-pasteable checklist for quick extension reference.

Please refer to the full design and extension guidelines below.

  • the estimator should inherit from sktime's BaseForecaster. The BaseForecaster class inherits from sklearn's BaseEstimator class, so satisfies the template inheritance requirements.
  • the estimator must implement fit(self, y, X=None, fh=None). This is first time model fitting. Arguments are y : pd.Series initial time series observations; X : pd.DataFrame exogeneous time series; optional: fh : int, list, np.array, or ForecastingHorizon object - forecasting horizon.
  • fit must set the _is_fitted attribute to True.
  • optionlly, the estimator overrides update(self, y, X=None, update_params=True). This is model update with additional data after fit has been called. Arguments are y : pd.Series additional time series observations; X : pd.DataFrame exogeneous time series; update_params : Boolean controls whether model parameters are updated, or only data is ingested. If not overridden, update uses default logic from BaseForecaster which calls fit.
  • fit and update must set the attribute cutoff : int or numpy.datetime64 to most recent time stamp in y. If update is inherited, this is automatically done; fit needs to implement this explicitly.
  • the estimator must implement predict(self, fh=None, X=None). This is prediction after fit has been called. Arguments are X : pd.DataFrame exogeneous time series; mandatory: fh : int, list, np.array, or ForecastingHorizon object - forecasting horizon. Returns a forecast pd.Series at time indices fh.
  • consider using _SktimeForecaster and _OptionalForecastingHorizonMixin for extension. _SktimeForecaster provides additional templating functionality; it also inherits from BaseEstimator and BaseForecaster, so inheriting from _SktimeForecaster can replace inheriting from the two latter classes.
  • mandatory input checks using check_y_X, check_X, check_y, check_fh should be performed in fit, predict, and update (where applicable)

Optional functionality:

  • return_pred_int and alpha return objects for predict - prediction intervals
  • custom update_predict method

Conceptual model

Conceptual model: the data

Forecasters operate on the following conceptual data model with data objects:

  • observation times $t_1 < t_2 <\dots \in \mathbb{R}$, also called time stamps below.
  • endogeneous observation values $y_1, y_2,\dots \in E$, where $E$ is a data frame row domain which may include missing data (usually but not necessarily $\mathbb{R}^n$ for some $n\in \mathbb{N}$). The value $y_i$ is interpreted to be observed at time $t_i$; we will alternatively write $y(t_i)$ for $y_i$.
  • temporal exogeneous observation values $x_1, x_2, dotx, \in E'$, where $E'$ is a data frame row domain which may include missing data (usually but not necessarily $\mathbb{R}^{n'}$ for some $n'\in \mathbb{N}$). The value $x_i$ is interpreted to be observed at time $t_i$; we will alternatively write $x(t_i)$ for $x_i$.
  • non-temporal exogeneous observation values $x'_1, x'_2, dotx, \in E''$, where $E''$ is a data frame row domain which may include missing data (usually but not necessarily $\mathbb{R}^{n'}$ for some $n'\in \mathbb{N}$). The value $x'_i$ is interpreted to be observed at time $t_i$; we will alternatively write $x'(t_i)$ for $x'_i$.

Of all indices occurring above, there are potentially infinitely many.

The data model above does not distinguish whether data has been actually "observed"; it only specifies the objects that in-principle can be observed.

The endogeneous and temporal exogeneous values are assumed to be "temporal", i.e., $y(t_i)$ is in-principle knowable/measurable only if current time is larger than $t_i$. The temporal exogeneous values are assumed to be "non-temporal", i.e., in-principle knowable irrespective of current time (or ahead of current time for all practical purposes).

Conceptual model: forecaster

A forecaster is a parametric entity object (or stateful object) that has the following state variables:

  • $\tau\in \mathbb{R}$, called the cut-off. Intuitively, $\tau$ is the forecaster's present time, i.e., a "now-time" state variable.
  • a model representation, without any explicit domain specification.

A forecaster has two states:

  • unfitted - in this state, no data has been ingested. In this state, the state variables are not set.
  • fitted - in this state, some data has been ingested. In this state, a model representation and a cut-off are set.

A forecaster can transition from unfitted to fitted; once fitted, it remains fitted.

A forecaster has the following scitype-defining methods:

  • fit - fitting, "first time ingesting of data". This method is invoked at some current time $T$. This method gives the forecaster access to some $t_i$, and some or all $x'(t_i)$; it also gives access to some $y(t_i), x(t_i)$ where $t_i\le T$. The method updates the state variable $\tau \leftarrow T$, stores a model representation, and sets the forecaster's state to fitted. Intuitively, invoking fit models the first time behaviour when data is ingested to the forecaster.
  • predict - forecasting or prediction. This method requires the forecaster to be in fitted state. This method queries and outputs predictions $\widehat{y}(t'_i)$ for some $y(t'_i)$. The query is passed to the method as the (finite length) sequence $t'_1,\dots, t'_N$ for which predictions are queried; the method returns the predictions $\widehat{y}(t'_i)$. In addition, some or all $x'(t'_i)$ may be passed here. The state is not changed. It is not necessarily assumed that $t'_i > \tau$ for all $i$, i.e., some predictions might be "hindcasts" instead of foreasts in the strict sense.
  • update - updating the forecaster with new data, "ingesting additional data", while time progresses. This method requires the forecaster to be in fitted state. This method is called at some time $T>\tau$, and sets the state $\tau$ to the new current time $T$. It gives the forecaster access to some additional $t_i$, and some or all $x'(t_i)$; it also gives access to some $y(t_i), x(t_i)$ where $t_i\le T$. The method updates the model representation. The state is not changed. Intuitively, invoking update models the process of updating model representation as time progresses, ingesting additional data.

The concrete implementation of the three methods fit, predict, update combined defines a specific forecaster; behaviour is possibly parametric, dependent on the same parameters as the forecaster.

Note: it is expressly not assumed nor excluded that ingesting data in multiple chunks through fit and multiple uses of update results in the same model representation as ingesting the same data as a singel chunk, through a single application of fit.

Restrictions of implemented interface

In comparison to the fulll conceptual model, a number of restrictions apply to the conceptual model supported by the sktime interface:

  • support only for univariate endogenous observations, i.e., $E$ is a primitive value domain, i.e., $E$ is finite (categorical) or $E=\mathbb{R}$. This is a major restriction, and we aim to provide support for multivariate endogeneous observations in the future.
  • when ingesting data through fit, the latest timestamp is assumed to be identical with the present time; i.e., when ingesting data with times $t_1,\dots, t_N$, the cut-off $\tau$ is always set to $t_N$ (this is not the case for update)
  • no declarative distinction between temporal and non-temporal exogeneous observations.

Software interface specification

This section describes the interface contract that any estimator following the forecaster scitype are expected to fulfil.

Core interface

Forecasters are represented as classes.

State variables are represented as follows:

  • _is_fitted : Boolean; whether the model is in fitted state (True) or unfitted (False).
  • model representation is through any number of private variables. Variables corresponding to model state representation should start with underscore.
  • cutoff : int or numpy.datetime64; cut-off, models $\tau$

The core interface of forecasters consists of the following methods:

__init__(self, ...)

Behaviour: construction and initialization of estimator. Used for specification.

Requirements:

  • hyper-parameters should be named arguments, and should be written to variables with identical name in self.
  • components should be sklearn estimators.
  • __init__ should set the flag _is_fitted to False.
fit(self, y, X=None, fh=None)

Parameters:

  • y : pd.Series; this models the $y(t_i)$ and $t_i$ to which access is given in fit. The $y(t_i)$ are the entries of y, and $t_i$ are y.index.
  • X : pd.DataFrame; this models $x(t_i)$ and $x'(t_i)$ to which access is given in fit. The $x(t_i)$ and $x'(t_i)$ are the entries of X, with different components being the different variables of X. The $t_i$ are X.index.
  • fh : int, list, np.array, or ForecastingHorizon object; for some forecasters, the information on the query on predict already needs to be passed on fit - this should be the same object, see below in predict.

Behaviour:

  • fits a model and writes representation to any number of private variables representing the model to self.
  • sets the cut-off to the largest of the $t_i$ passed in y, i.e., the largest element of y.index
  • sets _is_fitted to True
  • should have no side effects on arguments

Returns: self

predict(self, fh=None, X=None):
  • fh : int, list, np.array, or ForecastingHorizon object; encodes the query to predict in the form of time indices $t_i$ at which to produce the predictions $\widehat{y}(t_i)$, as predictions for unknown $y(t_i)$.
  • X : pd.DataFrame; this models $x'(t_i)$ to which access is given in predict. The $x'(t_i)$ are the entries of X, with different components being the different variables of X. The $t_i$ are X.index. For easy implementation, it can be assumed that $x'(t_i)$ with $t_i>\tau$ are seen/passed only in predict.

Behaviour:

  • accesses model representation and produces predictions
  • should have no side effects on arguments
  • should not change state variables

Returns:

  • y_pred : pd.Series: this models the predictions $\widehat{y}(t_i)$ and $t_i$ for the $t_i$ encoded in fh. The $\widehat{y}(t_i)$ are the entries of y_pred, and $t_i$ are y_pred.index.
update(self, y, X=None, update_params=True):
  • y : pd.Series; this models the $y(t_i)$ and $t_i$ to which access is given in update. The $y(t_i)$ are the entries of y, and $t_i$ are y.index.
  • X : pd.DataFrame; this models $x(t_i)$ and $x'(t_i)$ to which access is given in update. The $x(t_i)$ and $x'(t_i)$ are the entries of X, with different components being the different variables of X. The $t_i$ are X.index.
  • update_params : Boolean; this is a switch for the behaviour of update. If True, models default behaviour. If False, overrides the behaviour to prevent updating of model parameters.

Behaviour if update_params=True:

  • retrieves then updates model representation, writes updates representation to any number of private variables representing the model to self.
  • sets the cut-off to the largest of the $t_i$ passed in y, i.e., the largest element of y.index
  • should have no side effects on arguments

Behaviour if update_params=False:

  • sets the cut-off to the largest of the $t_i$ passed in y, i.e., the largest element of y.index
  • should have no side effects on arguments
  • may change model representation (e.g., through storing y and X internally), but should not have an effect on subsequent calls of predict until update is called with argument update_params=True

Returns: self

get_params, set_params

This should implement parameter access and follow the sklearn specifications verbatim.

todo: add update_predict, score, get_fitted_params

Inheritance requirements and class template

Forecasters should inherit from:

  • sklearn's BaseEstimator which provides hyper-parameter interface and estimator composition functionality
  • sktime's BaseForecaster which provides scitype specific template functionality

Mandatory methods to implement and requirements

talk about type checks here

Default behaviour of non-mandatory core methods

Optional arguments to mandatory methods and optional behaviour

todo: return_pred_int and alpha for predict

Optional methods to implement

update update_predict update_predict_single