sciedm.SMap#

class sciedm.SMap(columns=None, target=None, E=1, tau=-1, Tp=1, lib=None, pred=None, theta=0.0, solver=None, knn=0, exclusionRadius=0, embedded=False, noTime=False)#

S-map projection of target variable from embedding library

Sequential locally weighted global linear maps (s-map).

Parameters:
columns[str]

Vector of column names used to create embedding library

targetstr

DataFrame column name of target feature to predict

thetafloat

Exponential scale factor for knn weight kernel

Eint

Embedding dimension applied in time delay embedding

tauint

Embedding time delay offset. Negative are delays, positive future values.

Tpint

Prediction horizon in units of time series row indices

lib[int]

Vector of pairs of 1-offset integer indices defining the embedding library The first index of a pair is the start index, the second the stop index. Default lib=None will assign lib=[1,N_obs] where N_obs is the number of observations. lib is _not_ 0-offset but ranges from 1 to N_obs.

pred[int]

Vector of pairs of 1-offset integer indices defining target prediction times The first index of a pair is the start index, the second the stop index. Default pred=None will assign pred=[1,N_obs] where N_obs is the number of observations. pred is _not_ 0-offset but ranges from 1 to N_obs.

knnint

Number of k-nearest neighbors for the simplex. If default knn=0 it is set to E+1 for Simplex, and to N_obs for SMap.

exclusionRadiusint

Temporal exclusion radius for nearest neighbors. Neighbors closer than exclusionRadius indices from the target are ignored. Only applicable if lib and pred overlap.

embeddedbool

Is the input an embedding? If False (default) all columns will be time delay embedded with E and tau.

noTimebool

X is expected to be DataFrame with time index/values/strings in first column. If no time vector is provided set noTime=True.

Attributes:
is_fitted_bool

A boolean indicating whether the estimator has been fitted.

n_features_in_int

Number of features seen during fit.

feature_names_in_ndarray of shape (n_features_in_,)

Names of features seen during fit. Defined only when X has feature names that are all strings.

Embedding_DataFrame

Embedding of X from which predictions are made

Projection_DataFrame

DataFrame with columns ‘Time’, ‘Observations’, ‘Predictions’, ‘Pred_Variance’ of the Simplex projection

Coefficients_DataFrame

DataFrame with columns “Time” and E+1 SMap coefficents at each time step

SingularValues_DataFrame

DataFrame with columns “Time” and E+1 SMap singular values at each time step

lib_i_ndarray

List of library indices identifying time points from which embedding vectors are used for the projection

pred_i_ndarray

List of indices identifying time points at which embedding vectors are used to make the projection

knn_neighbors_ndarray

Matrix of k-nearest neighbors at each prediction time

knn_distances_ndarray

Matrix of k-nearest neighbors distances at each prediction time

Returns:
Vector of predictions of target (y) at forecast horizon Tp.

Examples

>>> from sciedm import SMap
>>> from pandas import DataFrame
>>> df = DataFrame({'time':[t for t in range(1,21)],
                    'x':[1,1,3,4,5,5,6,8,3,3,2,6,5,5,9,3,5,1,8,2],
                    'y':[5,5,7,8,6,6,7,8,2,2,2,8,3,3,7,5,3,1,1,1]})
>>> smap = SMap(columns='x',target='y',E=2,theta=3.)
>>> smap.fit(df)
Simplex(E=2, columns='x', target='y')
>>> smap.predict(df)
AddTime(Tp_magnitude, outSize, obs_i, obsOut_i)#

Prepend or append time values to self._time if needed Return timeOut vector with additional Tp points

ConvertTime()#

Replace self._time with ndarray numerically operable values ISO 8601 formats are supported in the time & datetime modules

CreateIndices()#

Populate array index vectors lib_i, pred_i Indices specified in list of pairs [ 1,10, 31,40… ] where each pair is start:stop span of data rows.

EDM_params()#

Validate parameters and data passed to .fit()

EmbedData()#

Embed data : If not embedded call Embed()

FindNeighbors()#

Use Scipy KDTree to find neighbors

Note: If dimensionality is k, the number of points n in the data should be n >> 2^k, otherwise KDTree efficiency is low. k:2^k pairs { 4 : 16, 5 : 32, 7 : 128, 8 : 256, 10 : 1024 }

KDTree returns ndarray of knn_neighbors as indices with respect to the data array passed to KDTree, not with respect to the lib_i of embedding[ lib_i ] passed to KDTree. Since lib_i are generally not [0..N] the knn_neighbors need to be adjusted to lib_i reference for use in projections. If the the library is unitary this is a simple shift by lib_i[0]. If the library has disjoint segments or unordered indices, a mapping is needed from KDTree to lib_i.

If there are degenerate lib & pred indices the first nn will be the prediction vector itself with distance 0. These are removed to implement “leave-one-out” prediction validation. In this case self._libOverlap is set True and the value of knn is increased by 1 to return an additional nn. The first nn is relplaced by shifting the j = 1:knn+1 knn columns into the j = 0:knn columns.

If exlcusionRadius > 0, and, there are degenerate lib & pred indices, or, if there are not degnerate lib & pred but the distance in rows between the lib & pred gap is less than exlcusionRadius, knn_neighbors have to be selected for each pred row to exclude library neighbors within exlcusionRadius. This is done by increasing knn to KDTree.query by a factor of self._xRadKnnFactor, then selecting valid nn.

Writes to EDM object:

knn_distances : sorted knn distances knn_neighbors : library neighbor rows of knn_distances

FormatProjection()#

Create Projection, Coefficients, SingularValues DataFrames AddTime() attempts to extend forecast time if needed

NOTE: self.pred_i_ had all nan removed for KDTree by RemoveNan().

self._predList only had leading/trailing embedding nan removed. Here we want to include any nan observation rows so we process predList & pred_i_all, not self.pred_i_.

PredictionValid()#

Validate there are pred_i to make a prediction

Project()#

For each prediction row compute projection as the linear combination of regression coefficients (C) of weighted embedding vectors (A) against target vector (B) : AC = B.

Weights reflect the SMap theta localization of the knn for each prediction. Default knn = len( lib_i ).

Matrix A has (weighted) constant (1) first column to enable a linear intercept/bias term.

Sugihara (1994) doi.org/10.1098/rsta.1994.0106

RemoveNan()#

KDTree in Neighbors does not accept nan If ignoreNan remove Embedding rows with nan from lib_i, pred_i

Solver(A, wB)#

Call SMap solver. Default is numpy.lstsq

Validate()#

Validate DataFrame columns/target in .fit()

fit(X, y=None)#

Initialize lib & pred indices, embed data, find neighbors

Parameters:
X{array-like}, shape (n_samples, n_features)

Observed data to be embedded, or used as embedding.

yaccepted but silently ignored — embedding is target-independent
Returns:
selfobject

Returns self.

get_feature_names_out(input_features=None)#

Set_output for downstream pipeline compatibility See https://scikit-learn.org/stable/developers/develop.html#

developer-api-for-set-output

To usefully label cross mapped components, use both _columns and _target attributes in the generated name.

get_metadata_routing()#

Get metadata routing of this object.

Please check User Guide on how the routing mechanism works.

Returns:
routingMetadataRequest

A MetadataRequest encapsulating routing information.

get_params(deep=True)#

Get parameters for this estimator.

Parameters:
deepbool, default=True

If True, will return the parameters for this estimator and contained subobjects that are estimators.

Returns:
paramsdict

Parameter names mapped to their values.

predict(X)#

SMap projection of target variable from embedding library

Parameters:
X{array-like}, shape (n_samples, n_features)

Not used but accepted for sklearn convention.

Returns:
yndarray, shape (n_samples,)
score(X, y, sample_weight=None)#

Return : coefficient of determination <r2_score> on test data.

Override RegessorMixin score() method since predict(X) does not actually depend on X (the data passed to Simplex) but on the embedding created in fit(). Once the embedding is created it is used to project a target y. If a new model/embedding is desired based on X, a new fit() is required to build the embedding.

Both the embedding and the target projection are dictated by the lib and pred parameters defining the time series observation rows of the library and prediction set. By default lib = pred = [1,N] (all data) but in general lib and pred are disjoint (out-of-sample).

The embedding is also governed by E & tau, and the prediction by Tp.

Parameters:
Xarray-like of shape (n_samples, n_features)

Test samples.

yarray-like of shape (n_samples,) or (n_samples, n_outputs)

True values for estimate of y based on embedding of X.

sample_weightarray-like of shape (n_samples,), default=None

Sample weights. Not used.

Returns:
scorefloat

:math:R^2 of self.fit(X).predict(X) w.r.t. y.

set_params(**params)#

Set the parameters of this estimator.

The method works on simple estimators as well as on nested objects (such as Pipeline). The latter have parameters of the form <component>__<parameter> so that it’s possible to update each component of a nested object.

Parameters:
**paramsdict

Estimator parameters.

Returns:
selfestimator instance

Estimator instance.

set_score_request(*, sample_weight: bool | None | str = '$UNCHANGED$') SMap#

Configure whether metadata should be requested to be passed to the score method.

Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with enable_metadata_routing=True (see sklearn.set_config()). Please check the User Guide on how the routing mechanism works.

The options for each parameter are:

  • True: metadata is requested, and passed to score if provided. The request is ignored if metadata is not provided.

  • False: metadata is not requested and the meta-estimator will not pass it to score.

  • None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.

  • str: metadata should be passed to the meta-estimator with this given alias instead of the original name.

The default (sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.

Added in version 1.3.

Parameters:
sample_weightstr, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED

Metadata routing for sample_weight parameter in score.

Returns:
selfobject

The updated object.