Core Estimator#

estimator #

CLASS DESCRIPTION
Estimator

Base class for non-parametric methods.

Classes#

Estimator() #

Bases: Module, ABC

Base class for non-parametric methods.

This abstract base class provides a common interface for non-parametric methods that follow the scikit-learn pattern of fit, predict, and score.

All non-parametric methods (those not using neural networks) should inherit from this class.

The class tracks fitting state and provides consistent interfaces for training and prediction. Subclasses must implement the abstract methods fit, predict, and score.

ATTRIBUTE DESCRIPTION
in_features

Number of input features, set during fitting.

TYPE: int

out_features

Number of output features, set during fitting.

TYPE: int

is_fitted

Whether the estimator has been fitted to data.

TYPE: bool

Examples:

Basic usage example with a custom estimator:

>>> import torch
>>> from spectre.core import Estimator
>>> class MyEstimator(Estimator):
...     def fit(self, X, weights=None, target=None):
...         self.in_features = X.shape[1]
...         self.out_features = X.shape[1] // 2
...         self.is_fitted = True
...         return self
...
...     def predict(self, X):
...         self.check_fitted()
...         return X[:, : self.out_features]
...
...     def score(self, X, weights=None, target=None):
...         self.check_fitted()
...         return 1.0
>>> estimator = MyEstimator()
>>> X = torch.randn(100, 10)
>>> estimator.fit(X)
MyEstimator(in_features=10, out_features=5, fitted)
>>> preds = estimator.predict(X)
>>> score = estimator.score(X)
>>> print(preds.shape, score)
torch.Size([100, 5]) 1.0
METHOD DESCRIPTION
check_fitted

Check if the estimator is fitted and raise an error if not.

fit

Fit the estimator to the provided data.

predict

Make predictions on new data using the fitted estimator.

transform

Transform data using the fitted estimator.

inverse_transform

Transform data back to original space.

score

Evaluate the performance of the fitted estimator.

fit_predict

Fit the estimator and immediately make predictions on the same data.

fit_transform

Fit the estimator and immediately transform the same data.

predict_proba

Predict class probabilities for input data.

predict_log_proba

Predict log probabilities for input data.

get_params

Get parameters for this estimator.

set_params

Set the parameters of this estimator.

Source code in spectre/core/estimator.py
def __init__(self) -> None:
    super().__init__()

    self._in_features: int | None = None
    self._out_features: int | None = None
    self._is_fitted: bool = False
Attributes#
in_features: int property writable #

Number of input features.

out_features: int property writable #

Number of output features.

is_fitted: bool property writable #

Whether the estimator has been fitted to data.

Functions#
check_fitted() -> None #

Check if the estimator is fitted and raise an error if not.

This method should be called by :meth:predict and :meth:score methods to ensure the estimator has been fitted before use.

Source code in spectre/core/estimator.py
def check_fitted(self) -> None:
    """
    Check if the estimator is fitted and raise an error if not.

    This method should be called by :meth:`predict` and :meth:`score` methods
    to ensure the estimator has been fitted before use.
    """
    if not self.is_fitted:
        raise ValueError("Estimator is not fitted. Call `fit()` first.")
fit(X: torch.Tensor, weights: torch.Tensor | None = None, target: torch.Tensor | None = None) -> Estimator abstractmethod #

Fit the estimator to the provided data.

This method trains the estimator on the input data, with optional weights and target values. After fitting, the estimator should be ready for prediction and the is_fitted property should be set to True.

PARAMETER DESCRIPTION
X

Training data of shape (n_samples, in_features).

TYPE: Tensor

weights

Sample weights of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

target

Target values for supervised learning of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

RETURNS DESCRIPTION
Estimator

Returns self for method chaining.

Source code in spectre/core/estimator.py
@abstractmethod
def fit(
    self,
    X: torch.Tensor,
    weights: torch.Tensor | None = None,
    target: torch.Tensor | None = None,
) -> "Estimator":
    """
    Fit the estimator to the provided data.

    This method trains the estimator on the input data, with optional weights
    and target values. After fitting, the estimator should be ready for prediction
    and the `is_fitted` property should be set to True.

    Parameters
    ----------
    X : torch.Tensor
        Training data of shape (n_samples, in_features).

    weights : torch.Tensor | None, optional, by default None
        Sample weights of shape (n_samples, ).

    target : torch.Tensor | None, optional, by default None
        Target values for supervised learning of shape (n_samples, ).

    Returns
    -------
    Estimator
        Returns self for method chaining.
    """
    raise NotImplementedError()
predict(X: torch.Tensor) -> torch.Tensor abstractmethod #

Make predictions on new data using the fitted estimator.

This method applies the fitted estimator to new input data to generate predictions. The estimator must be fitted before calling this method.

For dimensionality reduction methods, this is semantically equivalent to transform. For other methods, this generates actual predictions.

PARAMETER DESCRIPTION
X

Input data of shape (n_samples, in_features).

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

Predicted outputs of shape (n_samples, out_features).

Source code in spectre/core/estimator.py
@abstractmethod
def predict(self, X: torch.Tensor) -> torch.Tensor:
    """
    Make predictions on new data using the fitted estimator.

    This method applies the fitted estimator to new input data to generate
    predictions. The estimator must be fitted before calling this method.

    For dimensionality reduction methods, this is semantically equivalent to
    `transform`. For other methods, this generates actual predictions.

    Parameters
    ----------
    X : torch.Tensor
        Input data of shape (n_samples, in_features).

    Returns
    -------
    torch.Tensor
        Predicted outputs of shape (n_samples, out_features).
    """
    raise NotImplementedError()
transform(X: torch.Tensor) -> torch.Tensor #

Transform data using the fitted estimator.

This method provides sklearn-compatible interface for dimensionality reduction and feature extraction. It is an alias for predict to maintain consistency with scikit-learn's API conventions.

The estimator must be fitted before calling this method.

PARAMETER DESCRIPTION
X

Input data of shape (n_samples, in_features).

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

Transformed outputs of shape (n_samples, out_features).

Source code in spectre/core/estimator.py
def transform(self, X: torch.Tensor) -> torch.Tensor:
    """
    Transform data using the fitted estimator.

    This method provides sklearn-compatible interface for dimensionality
    reduction and feature extraction. It is an alias for `predict`
    to maintain consistency with scikit-learn's API conventions.

    The estimator must be fitted before calling this method.

    Parameters
    ----------
    X : torch.Tensor
        Input data of shape (n_samples, in_features).

    Returns
    -------
    torch.Tensor
        Transformed outputs of shape (n_samples, out_features).
    """
    return self.predict(X)
inverse_transform(X: torch.Tensor) -> torch.Tensor #

Transform data back to original space.

For reversible dimensionality reduction methods (PCA, Linear methods), reconstruct the original data from the transformed representation.

PARAMETER DESCRIPTION
X

Transformed data of shape (n_samples, out_features).

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

Reconstructed data of shape (n_samples, in_features).

RAISES DESCRIPTION
NotImplementedError

If the estimator does not support inverse transformation.

Source code in spectre/core/estimator.py
def inverse_transform(self, X: torch.Tensor) -> torch.Tensor:
    """
    Transform data back to original space.

    For reversible dimensionality reduction methods (PCA, Linear methods),
    reconstruct the original data from the transformed representation.

    Parameters
    ----------
    X : torch.Tensor
        Transformed data of shape (n_samples, out_features).

    Returns
    -------
    torch.Tensor
        Reconstructed data of shape (n_samples, in_features).

    Raises
    ------
    NotImplementedError
        If the estimator does not support inverse transformation.
    """
    raise NotImplementedError(
        f"{type(self).__name__} does not implement `inverse_transform()`. "
        f"This estimator does not support reversible transformations."
    )
score(X: torch.Tensor, weights: torch.Tensor | None = None, target: torch.Tensor | None = None) -> torch.Tensor | float abstractmethod #

Evaluate the performance of the fitted estimator.

This method computes a performance score for the estimator on the provided data. The exact metric depends on the specific estimator implementation (e.g., likelihood, reconstruction error, etc.).

PARAMETER DESCRIPTION
X

Input data of shape (n_samples, in_features).

TYPE: Tensor

weights

Sample weights of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

target

Target values for evaluation of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

RETURNS DESCRIPTION
Tensor | float

Performance score (higher is typically better).

Source code in spectre/core/estimator.py
@abstractmethod
def score(
    self,
    X: torch.Tensor,
    weights: torch.Tensor | None = None,
    target: torch.Tensor | None = None,
) -> torch.Tensor | float:
    """
    Evaluate the performance of the fitted estimator.

    This method computes a performance score for the estimator on the provided data.
    The exact metric depends on the specific estimator implementation (e.g.,
    likelihood, reconstruction error, etc.).

    Parameters
    ----------
    X : torch.Tensor
        Input data of shape (n_samples, in_features).

    weights : torch.Tensor | None, optional, by default None
        Sample weights of shape (n_samples, ).

    target : torch.Tensor | None, optional, by default None
        Target values for evaluation of shape (n_samples, ).

    Returns
    -------
    torch.Tensor | float
        Performance score (higher is typically better).
    """
    raise NotImplementedError()
fit_predict(X: torch.Tensor, weights: torch.Tensor | None = None, target: torch.Tensor | None = None) -> torch.Tensor #

Fit the estimator and immediately make predictions on the same data.

This is a convenience method that combines fit and predict in a single call. It is equivalent to calling fit followed by predict.

PARAMETER DESCRIPTION
X

Training and prediction data of shape (n_samples, in_features).

TYPE: Tensor

weights

Sample weights of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

target

Target values for supervised learning of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

RETURNS DESCRIPTION
Tensor

Predicted outputs of shape (n_samples, out_features).

Source code in spectre/core/estimator.py
def fit_predict(
    self,
    X: torch.Tensor,
    weights: torch.Tensor | None = None,
    target: torch.Tensor | None = None,
) -> torch.Tensor:
    """
    Fit the estimator and immediately make predictions on the same data.

    This is a convenience method that combines `fit` and `predict` in
    a single call. It is equivalent to calling `fit` followed by `predict`.

    Parameters
    ----------
    X : torch.Tensor
        Training and prediction data of shape (n_samples, in_features).

    weights : torch.Tensor | None, optional, by default None
        Sample weights of shape (n_samples, ).

    target : torch.Tensor | None, optional, by default None
        Target values for supervised learning of shape (n_samples, ).

    Returns
    -------
    torch.Tensor
        Predicted outputs of shape (n_samples, out_features).
    """
    self.fit(X, weights=weights, target=target)

    return self.predict(X)
fit_transform(X: torch.Tensor, weights: torch.Tensor | None = None, target: torch.Tensor | None = None) -> torch.Tensor #

Fit the estimator and immediately transform the same data.

This is a convenience method that combines fit and transform in a single call. It is equivalent to calling fit followed by transform. This method provides sklearn-compatible interface.

PARAMETER DESCRIPTION
X

Training and transformation data of shape (n_samples, in_features).

TYPE: Tensor

weights

Sample weights of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

target

Target values for supervised learning of shape (n_samples, ).

TYPE: torch.Tensor | None, optional, by default None DEFAULT: None

RETURNS DESCRIPTION
Tensor

Transformed outputs of shape (n_samples, out_features).

Source code in spectre/core/estimator.py
def fit_transform(
    self,
    X: torch.Tensor,
    weights: torch.Tensor | None = None,
    target: torch.Tensor | None = None,
) -> torch.Tensor:
    """
    Fit the estimator and immediately transform the same data.

    This is a convenience method that combines `fit` and `transform`
    in a single call. It is equivalent to calling `fit` followed by
    `transform`. This method provides sklearn-compatible interface.

    Parameters
    ----------
    X : torch.Tensor
        Training and transformation data of shape (n_samples, in_features).

    weights : torch.Tensor | None, optional, by default None
        Sample weights of shape (n_samples, ).

    target : torch.Tensor | None, optional, by default None
        Target values for supervised learning of shape (n_samples, ).

    Returns
    -------
    torch.Tensor
        Transformed outputs of shape (n_samples, out_features).
    """
    self.fit(X, weights=weights, target=target)
    return self.transform(X)
predict_proba(X: torch.Tensor) -> torch.Tensor #

Predict class probabilities for input data.

For classification methods, returns probability estimates for each class. For clustering methods, returns soft assignments.

PARAMETER DESCRIPTION
X

Input data of shape (n_samples, in_features).

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

Class probabilities of shape (n_samples, n_classes) or (n_samples, n_clusters).

RAISES DESCRIPTION
NotImplementedError

If the estimator does not support probabilistic predictions.

Source code in spectre/core/estimator.py
def predict_proba(self, X: torch.Tensor) -> torch.Tensor:
    """
    Predict class probabilities for input data.

    For classification methods, returns probability estimates for
    each class. For clustering methods, returns soft assignments.

    Parameters
    ----------
    X : torch.Tensor
        Input data of shape (n_samples, in_features).

    Returns
    -------
    torch.Tensor
        Class probabilities of shape (n_samples, n_classes) or
        (n_samples, n_clusters).

    Raises
    ------
    NotImplementedError
        If the estimator does not support probabilistic predictions.
    """
    raise NotImplementedError(
        f"{type(self).__name__} does not implement predict_proba(). "
        f"This estimator does not provide probabilistic outputs."
    )
predict_log_proba(X: torch.Tensor) -> torch.Tensor #

Predict log probabilities for input data.

Numerically more stable than log(predict_proba(X)) by clamping probabilities to avoid log(0) which would produce -inf.

PARAMETER DESCRIPTION
X

Input data of shape (n_samples, in_features).

TYPE: Tensor

RETURNS DESCRIPTION
Tensor

Log probabilities of shape (n_samples, n_classes).

RAISES DESCRIPTION
NotImplementedError

If the estimator does not support probabilistic predictions.

Source code in spectre/core/estimator.py
def predict_log_proba(self, X: torch.Tensor) -> torch.Tensor:
    """
    Predict log probabilities for input data.

    Numerically more stable than `log(predict_proba(X))` by clamping
    probabilities to avoid `log(0)` which would produce `-inf`.

    Parameters
    ----------
    X : torch.Tensor
        Input data of shape (n_samples, in_features).

    Returns
    -------
    torch.Tensor
        Log probabilities of shape (n_samples, n_classes).

    Raises
    ------
    NotImplementedError
        If the estimator does not support probabilistic predictions.
    """
    probs = self.predict_proba(X)
    return torch.log(probs.clamp(min=torch.finfo(probs.dtype).eps))
get_params(deep: bool = True) -> dict[str, Any] #

Get parameters for this estimator.

PARAMETER DESCRIPTION
deep

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

TYPE: bool, by default True DEFAULT: True

RETURNS DESCRIPTION
dict[str, Any]

Parameter names mapped to their values.

Examples:

>>> from sklearn.model_selection import GridSearchCV
>>> pca = PrincipalComponentAnalysis(out_features=10, standardize=True)
>>> params = pca.get_params()  # {'out_features': 10, 'standardize': True}
>>> pca.set_params(out_features=5)  # PCA(out_features=5, standardize=True)

Works with sklearn GridSearchCV:

>>> param_grid = {"out_features": [3, 5, 10], "standardize": [True, False]}
>>> grid_search = GridSearchCV(pca, param_grid)
Source code in spectre/core/estimator.py
def get_params(self, deep: bool = True) -> dict[str, Any]:
    """
    Get parameters for this estimator.

    Parameters
    ----------
    deep : bool, by default True
        If True, return parameters for this estimator and
        contained subobjects that are estimators.

    Returns
    -------
    dict[str, Any]
        Parameter names mapped to their values.

    Examples
    --------
    >>> from sklearn.model_selection import GridSearchCV
    >>> pca = PrincipalComponentAnalysis(out_features=10, standardize=True)
    >>> params = pca.get_params()  # {'out_features': 10, 'standardize': True}
    >>> pca.set_params(out_features=5)  # PCA(out_features=5, standardize=True)

    Works with sklearn GridSearchCV:

    >>> param_grid = {"out_features": [3, 5, 10], "standardize": [True, False]}
    >>> grid_search = GridSearchCV(pca, param_grid)
    """
    out = {}
    for key in self._get_param_names():
        value = getattr(self, key)
        if deep and hasattr(value, "get_params") and not isinstance(value, type):
            deep_items = value.get_params(deep=True).items()
            out.update((key + "__" + k, val) for k, val in deep_items)
        out[key] = value
    return out
set_params(**params) -> Estimator #

Set the parameters of this estimator.

PARAMETER DESCRIPTION
**params

Estimator parameters.

TYPE: dict DEFAULT: {}

RETURNS DESCRIPTION
Estimator

Returns self for method chaining.

Source code in spectre/core/estimator.py
def set_params(self, **params) -> "Estimator":
    """
    Set the parameters of this estimator.

    Parameters
    ----------
    **params : dict
        Estimator parameters.

    Returns
    -------
    Estimator
        Returns self for method chaining.
    """
    if not params:
        return self

    valid_params = self.get_params(deep=True)

    nested_params = {}
    for key, value in params.items():
        key_parts = key.split("__", 1)
        if len(key_parts) > 1:
            # Nested parameter
            nested_params.setdefault(key_parts[0], {})[key_parts[1]] = value
        else:
            if key not in valid_params:
                raise ValueError(
                    f"Invalid parameter {key} for estimator {type(self).__name__}."
                )
            setattr(self, key, value)

    for key, sub_params in nested_params.items():
        attr = getattr(self, key, None)
        if attr is None:
            raise ValueError(
                f"Cannot set nested params on None attribute '{key}' "
                f"for estimator {type(self).__name__}."
            )
        attr.set_params(**sub_params)

    return self

Functions#