pretab.transformers.TensorProductSplineTransformer

class pretab.transformers.TensorProductSplineTransformer(output_dim=UNSET, degree=3, diff_order=2, include_bias=False, placement_strategy='uniform', adaptive=False, min_output_dim=UNSET, max_output_dim=UNSET)[source]

Bases: SplineBasisMixin, TransformerMixin, BaseEstimator

Tensor Product Spline Transformer for multivariate smooth basis expansion.

This transformer generates tensor-product B-spline basis functions for multivariate input, allowing for smooth modeling of complex feature interactions. It supports regularization via difference penalties in each marginal dimension, suitable for additive models and structured regression.

output_dim here is per marginal dimension: each of the \(d\) input features gets a marginal B-spline basis of \(m := \mathtt{output\_dim}\) columns (using \(K = \mathtt{output\_dim} - p - 1\) interior knots with a \(p + 1\) boundary pad, exactly like PSplineTransformer), and the full tensor-product design has

\[\text{total columns} = \mathtt{output\_dim}^{\,d}\]

columns ((output_dim + 1) ** d when include_bias=True). This is the one family where the total output width is not n_features * output_dim.

Parameters:
  • output_dim (int, default=4) – Number of non-bias output columns per marginal dimension (\(m\)). Must be at least degree + 1. The interior knots per dimension is output_dim - degree - 1.

  • degree (int, default=3) – Degree of the B-spline basis functions.

  • diff_order (int, default=2) – Order of the finite difference penalty used to enforce smoothness along each input dimension.

  • include_bias (bool, default=False) – If True, prepend a constant column to each marginal basis before the tensor product. The bias term is left unpenalized.

  • placement_strategy ({"uniform", "quantile"}, default="uniform") –

    Interior-knot placement rule for each marginal dimension. "uniform" spaces knots evenly; "quantile" uses data quantiles.

    Note

    The tensor-product spline is a penalized (difference-penalty) spline per marginal, exactly like PSplineTransformer, so it assumes equally-spaced knots and is unsupervised-only: target-aware placement does not apply and only "uniform" / "quantile" spacing is accepted.

  • adaptive (bool, default=False) – Retained for API parity but a no-op for this unsupervised-only family: the per-marginal width is always fixed to output_dim.

  • min_output_dim (int or None, default=None) – Unused for this unsupervised-only family (kept for API parity).

  • max_output_dim (int or None, default=None) – Unused for this unsupervised-only family (kept for API parity).

Variables:
  • dim (int) – Number of input features (marginal dimensions).

  • knots (list of ndarray) – Full padded knot sequence for each marginal dimension.

  • n_knots (list of int) – Number of interior knots for each marginal dimension (output_dim - degree - 1 on the default, non-selector path).

  • bases (list of ndarray) – Marginal B-spline basis matrices, each of shape (n_samples, output_dim (+1 if include_bias)).

  • penalties (list of ndarray) – Univariate difference penalties for each marginal basis.

  • X_design (ndarray of shape (n_samples, output_dim ** dim_)) – Full tensor-product design matrix computed during fit.

  • n_features_in (int) – Number of input features seen during fit.

  • total_output_dim (int) – Total number of output columns (fitted); equals output_dim ** dim_ ((output_dim + 1) ** dim_ with a bias).

Notes

  • Uses einsum-based reshaping to build the tensor product basis efficiently.

  • Supports arbitrary number of input dimensions.

  • Commonly used in structured additive models and GAMs where smooth surfaces are desired [1], [2].

References

Examples

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> from pretab.transformers import TensorProductSplineTransformer
>>> X = rng.random((20, 2))
>>> transformer = TensorProductSplineTransformer(output_dim=6)
>>> Xt = transformer.fit_transform(X)
>>> Xt.shape
(20, 36)
>>> transformer.total_output_dim_
36
__init__(output_dim=UNSET, degree=3, diff_order=2, include_bias=False, placement_strategy='uniform', adaptive=False, min_output_dim=UNSET, max_output_dim=UNSET)[source]

Methods

__init__([output_dim, degree, diff_order, ...])

fit(X[, y])

fit_transform(X[, y])

Fit to data, then transform it.

get_feature_names_out([input_features])

Return names for the interaction basis as tp_{feat0 i}_{feat1 j}....

get_metadata_routing()

Get metadata routing of this object.

get_params([deep])

Get parameters for this estimator.

get_penalty_matrices()

Return the Kronecker-structured penalty matrices.

get_penalty_matrix([feature_index])

Return the marginal difference penalty for one input dimension.

set_output(*[, transform])

Set output container.

set_params(**params)

Set the parameters of this estimator.

transform(X)

Attributes

total_output_dim_

Total number of output columns produced across all input features.

n_basis_

n_features_in_

adaptive

get_feature_names_out(input_features=None)[source]

Return names for the interaction basis as tp_{feat0 i}_{feat1 j}....

get_penalty_matrices()[source]

Return the Kronecker-structured penalty matrices.

Returns:

penalties (list of ndarray) – One full penalty matrix per marginal direction, each formed as a Kronecker product of a marginal difference penalty with identity matrices for the remaining dimensions.

get_penalty_matrix(feature_index=0)[source]

Return the marginal difference penalty for one input dimension.

Provided for signature parity with the other spline transformers; use get_penalty_matrices() for the full Kronecker-structured penalties.

Parameters:

feature_index (int, default=0) – Index of the marginal dimension whose difference penalty is returned.

Returns:

P (ndarray) – The marginal difference penalty matrix for feature_index.