nemos.basis._transformer_basis.TransformerBasis#

class nemos.basis._transformer_basis.TransformerBasis(basis)[source]#

Bases: object

Basis as scikit-learn transformers.

This class abstracts the underlying basis function details, offering methods similar to scikit-learn’s transformers but specifically designed for basis transformations. It supports fitting to data (calculating any necessary parameters of the basis functions), transforming data (applying the basis functions to data), and both fitting and transforming in one step.

TransformerBasis, unlike Basis, is compatible with scikit-learn pipelining and model selection, enabling the cross-validation of the basis type and parameters, for example n_basis_funcs. See the example section below.

Parameters:

basis (Basis) – A concrete subclass of Basis.

Examples

>>> from nemos.basis import BSplineEval
>>> from nemos.basis import TransformerBasis
>>> from nemos.glm import GLM
>>> from sklearn.pipeline import Pipeline
>>> from sklearn.model_selection import GridSearchCV
>>> import numpy as np
>>> np.random.seed(123)
>>> # Generate data
>>> num_samples, num_features = 10000, 1
>>> x = np.random.normal(size=(num_samples, ))  # raw time series
>>> basis = BSplineEval(10)
>>> features = basis.compute_features(x)  # basis transformed time series
>>> weights = np.random.normal(size=basis.n_basis_funcs)  # true weights
>>> y = np.random.poisson(np.exp(features.dot(weights)))  # spike counts
>>> # transformer can be used in pipelines
>>> transformer = TransformerBasis(basis)
>>> pipeline = Pipeline([ ("compute_features", transformer), ("glm", GLM()),])
>>> pipeline = pipeline.fit(x[:, None], y)  # x need to be 2D for sklearn transformer API
>>> out = pipeline.predict(np.arange(10)[:, None]) # predict rate from new datas
>>> # TransformerBasis parameter can be cross-validated.
>>> # 5-fold cross-validate the number of basis
>>> param_grid = dict(compute_features__n_basis_funcs=[4, 10])
>>> grid_cv = GridSearchCV(pipeline, param_grid, cv=5)
>>> grid_cv = grid_cv.fit(x[:, None], y)
>>> print("Cross-validated number of basis:", grid_cv.best_params_)
Cross-validated number of basis: {'compute_features__n_basis_funcs': 10}
__init__(basis)[source]#
Parameters:

basis (Basis)

Methods

__init__(basis)

fit(X[, y])

Check the input structure and, if necessary, compute the convolutional kernels.

fit_transform(X[, y])

Compute the kernels and the features.

get_params([deep])

Extend the dict of parameters from the underlying Basis with basis.

set_params(**parameters)

Set TransformerBasis parameters.

transform(X[, y])

Transform the data using the fitted basis functions.

__add__(other)[source]#

Add two TransformerBasis objects.

Parameters:

other (TransformerBasis) – The other TransformerBasis object to add.

Returns:

The resulting Basis object.

Return type:

TransformerBasis

__dir__()[source]#

Extend the list of properties of methods with the ones from the underlying Basis.

Return type:

list[str]

__getattr__(name)[source]#

Enable easy access to attributes of the underlying Basis object.

This method caches all chainable methods (methods returning self) in a dicitonary. These methods are created the first time they are accessed by decorating the self.basis.name and cached for future use.

Examples

>>> from nemos import basis
>>> bas = basis.RaisedCosineLinearEval(5)
>>> trans_bas = basis.TransformerBasis(bas)
>>> bas.n_basis_funcs
5
>>> trans_bas.n_basis_funcs
5
Parameters:

name (str)

__getstate__()[source]#

Explicitly define how to pickle TransformerBasis object.

See https://docs.python.org/3/library/pickle.html#object.__getstate__ and https://docs.python.org/3/library/pickle.html#pickle-state

__mul__(other)[source]#

Multiply two TransformerBasis objects.

Parameters:

other (TransformerBasis) – The other TransformerBasis object to multiply.

Return type:

TransformerBasis

Returns:

The resulting Basis object.

__pow__(exponent)[source]#

Exponentiation of a TransformerBasis object.

Define the power of a basis by repeatedly applying the method __mul__. The exponent must be a positive integer.

Parameters:

exponent (int) – Positive integer exponent

Return type:

TransformerBasis

Returns:

The product of the basis with itself “exponent” times. Equivalent to self * self * … * self.

Raises:
  • TypeError – If the provided exponent is not an integer.

  • ValueError – If the integer is zero or negative.

__setattr__(name, value)[source]#

Allow setting basis or the attributes of basis with a convenient dot assignment syntax.

Setting any other attribute is not allowed.

Return type:

None

Raises:

ValueError – If the attribute being set is not basis or an attribute of basis.

Parameters:

name (str)

Examples

>>> import nemos as nmo
>>> trans_bas = nmo.basis.TransformerBasis(nmo.basis.MSplineEval(10))
>>> # allowed
>>> trans_bas.basis = nmo.basis.BSplineEval(10)
>>> # allowed
>>> trans_bas.n_basis_funcs = 20
>>> # not allowed
>>> try:
...     trans_bas.rand_atrr = "some value"
... except ValueError as e:
...     print(repr(e))
ValueError('Only setting basis or existing attributes of basis is allowed. Attempt to set `rand_atrr`.')
__setstate__(state)[source]#

Define how to populate the object’s state when unpickling.

Note that during unpickling a new object is created without calling __init__. Needed to avoid infinite recursion in __getattr__ when unpickling.

See https://docs.python.org/3/library/pickle.html#object.__setstate__ and https://docs.python.org/3/library/pickle.html#pickle-state

__sklearn_clone__()[source]#

Customize how TransformerBasis objects are cloned when used with sklearn.model_selection.

By default, scikit-learn tries to clone the object by calling __init__ using the output of get_params, which fails in our case.

For more info: https://scikit-learn.org/stable/developers/develop.html#cloning

Return type:

TransformerBasis

fit(X, y=None)[source]#

Check the input structure and, if necessary, compute the convolutional kernels.

Parameters:
  • X (TsdFrame | ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]) – The data to fit the basis functions to, shape (num_samples, num_input).

  • y (ignored) – Not used, present for API consistency by convention.

Returns:

The transformer object.

Return type:

self

Raises:
  • RuntimeError – If self.n_basis_input is None. Call self.set_input_shape before calling fit to avoid this.

  • ValueError: – If the number of columns in X do not self.n_basis_input_.

Examples

>>> import numpy as np
>>> from nemos.basis import MSplineEval, TransformerBasis
>>> # Example input
>>> X = np.random.normal(size=(100, 2))
>>> # Define and fit tranformation basis
>>> basis = MSplineEval(10).set_input_shape(2)
>>> transformer = TransformerBasis(basis)
>>> transformer_fitted = transformer.fit(X)
fit_transform(X, y=None)[source]#

Compute the kernels and the features.

This method is a convenience that combines fit and transform into one step.

Parameters:
  • X (TsdFrame | ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]) – The data to fit the basis functions to and then transform.

  • y – Not used, present for API consistency by convention.

Returns:

The data transformed by the basis functions, after fitting the basis functions to the data.

Return type:

array-like

Examples

>>> import numpy as np
>>> from nemos.basis import MSplineEval, TransformerBasis
>>> # Example input
>>> X = np.random.normal(size=(100, 1))
>>> # Define tranformation basis
>>> basis = MSplineEval(10).set_input_shape(1)
>>> transformer = TransformerBasis(basis)
>>> # Fit and transform basis
>>> feature_transformed = transformer.fit_transform(X)
get_params(deep=True)[source]#

Extend the dict of parameters from the underlying Basis with basis.

Return type:

dict

Parameters:

deep (bool)

set_params(**parameters)[source]#

Set TransformerBasis parameters.

When used with sklearn.model_selection, users can set either the basis attribute directly or the parameters of the underlying Basis, but not both.

Return type:

TransformerBasis

Examples

>>> from nemos.basis import BSplineEval, MSplineEval, TransformerBasis
>>> basis = MSplineEval(10)
>>> transformer_basis = TransformerBasis(basis=basis)
>>> # setting parameters of basis is allowed
>>> print(transformer_basis.set_params(n_basis_funcs=8).n_basis_funcs)
8
>>> # setting basis directly is allowed
>>> print(type(transformer_basis.set_params(basis=BSplineEval(10)).basis))
<class 'nemos.basis.basis.BSplineEval'>
>>> # mixing is not allowed, this will raise an exception
>>> try:
...     transformer_basis.set_params(basis=BSplineEval(10), n_basis_funcs=2)
... except ValueError as e:
...     print(repr(e))
ValueError('Set either new basis object or parameters for existing basis, not both.')
transform(X, y=None)[source]#

Transform the data using the fitted basis functions.

Parameters:
  • X (TsdFrame | ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]) – The data to transform using the basis functions, shape (num_samples, num_input).

  • y – Not used, present for API consistency by convention.

Return type:

TsdFrame | ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]

Returns:

The data transformed by the basis functions.

Examples

>>> import numpy as np
>>> from nemos.basis import MSplineConv, TransformerBasis
>>> # Example input
>>> X = np.random.normal(size=(10000, 2))
>>> basis = MSplineConv(10, window_size=200).set_input_shape(2)
>>> transformer = TransformerBasis(basis)
>>> # Before calling `fit` the convolution kernel is not set
>>> transformer.kernel_
>>> transformer_fitted = transformer.fit(X)
>>> # Now the convolution kernel is initialized and has shape (window_size, n_basis_funcs)
>>> transformer_fitted.kernel_.shape
(200, 10)
>>> # Transform basis
>>> feature_transformed = transformer.transform(X)