RandomEffectBasis

Random effect basis (one-hot encoding with identity penalty).

Usage

Source

RandomEffectBasis(k=-1)

A random effect basis represents a grouping factor — subject ID, site, batch, cluster — as a penalized random intercept rather than as a fixed factor with one unconstrained parameter per level. It is equivalent to mgcv’s bs="re" basis and to the random-intercept term of a linear mixed model: each unique level of the grouping variable gets its own one-hot column, and an identity penalty shrinks the estimated level effects toward their common mean, with the amount of shrinkage controlled by a single smoothing parameter selected by GCV or REML (equivalent to the group-level variance in a mixed model). Choose this basis over an ordinary fixed factor whenever the number of levels is large, levels have unbalanced sample sizes, or the goal is to borrow strength across levels rather than to estimate every level’s effect independently; choose it over MRFBasis or FactorSmoothBasis when the grouping levels have no spatial/ordering structure to exploit and only an exchangeable random intercept is wanted.

The covariate should be a 1-D array of group labels (strings, integers, or any hashable type).

Parameters

k: int = -1
Maximum number of levels to retain. If -1 (the default), all observed levels are kept as basis functions. If a positive integer smaller than the number of observed levels, only the first k (in sorted level order) are used and any other levels are silently dropped from the basis (their rows become all-zero); this is rarely desirable for a random effect, so the default of -1 should normally be left as-is unless there is a specific reason to cap the number of levels.

Notes

Let there be k unique levels of the grouping factor after fit(). The basis matrix B is the n x k matrix of level indicators, B[i, j] = 1 if observation i belongs to level j and 0 otherwise. The penalty matrix is the k x k identity,

\mathbf{S} = \mathbf{I}_k,

so the roughness penalty is simply the sum of squared level effects,

\boldsymbol{\beta}^\top \mathbf{S} \boldsymbol{\beta} = \sum_{j=1}^{k} \beta_j^2 ,

exactly the ridge-type penalty that shrinks every group deviation toward zero as lambda grows, with no level treated differently from any other. Because the identity matrix is full rank, null_space_dimension() is always 0 — there is no unpenalized subspace, and in principle the entire random effect can be shrunk away as lambda \to \infty, recovering a model with no group-level variation at all. Because the raw indicator columns are collinear with an overall intercept (every row sums to 1), identifiability_constraints() returns a sum-to-zero constraint that should be enforced when the random effect is fit alongside a fixed intercept term. fit() raises ValueError if fewer than two unique levels are present, since a random effect with a single level carries no information about between-group variation.

Examples

import numpy as np
from whittaker.smooths.random import RandomEffectBasis

rng = np.random.default_rng(0)
groups = rng.choice(["a", "b", "c", "d"], size=50)

basis = RandomEffectBasis().fit(groups)
B = basis.basis_matrix(groups)
S = basis.penalty_matrix()
B.shape, S.shape
((50, 4), (4, 4))

Attributes

Name Description
k Requested or actual number of group levels.
levels Sorted array of unique group labels retained during fit().
n_basis Number of basis functions, i.e. the number of retained group levels.

k

Requested or actual number of group levels.

k: int

Before fit() is called, returns the k value passed at construction (the requested cap on the number of levels, or -1 for “all levels”). After fit(), returns the actual number of group levels retained.


levels

Sorted array of unique group labels retained during fit().

levels: NDArray


n_basis

Number of basis functions, i.e. the number of retained group levels.

n_basis: int

Raises

RuntimeError
If accessed before fit() has been called.

Methods

Name Description
basis_matrix() Evaluate the one-hot random effect basis at x.
fit() Fit the random effect basis to training data.
identifiability_constraints() Return the sum-to-zero constraint row for the intercept.
null_space_dimension() Return 0: the identity penalty has no unpenalized subspace.
penalty_matrix() Return the (k, k) identity penalty matrix.

basis_matrix()

Evaluate the one-hot random effect basis at x.

Usage

Source

basis_matrix(x)

Parameters

x: NDArray
Grouping variable values. Shape (n,). Values not seen during fit() produce an all-zero row (no level indicator is set).

Returns

NDArray
Design matrix of shape (n, k) where k is the number of levels retained during fit(). Each row has at most one entry equal to 1.0.

fit()

Fit the random effect basis to training data.

Usage

Source

fit(x)

Determines the set of unique group levels present in x; these define the columns of the basis matrix produced by basis_matrix().

Parameters

x: NDArray
Training grouping variable. Shape (n,), of any hashable dtype (strings, integers, etc.).

Returns

RandomEffectBasis
Returns self for method chaining.

Raises

ValueError
If fewer than 2 unique levels are present in x, or if k is requested but is less than 2.

identifiability_constraints()

Return the sum-to-zero constraint row for the intercept.

Usage

Source

identifiability_constraints()

Returns

NDArray
A (1, k) matrix of equal weights 1 / k whose product with the coefficient vector forces the mean fitted level effect to be zero, resolving the confound between the random effect’s implicit constant and a fixed model intercept.

null_space_dimension()

Return 0: the identity penalty has no unpenalized subspace.

Usage

Source

null_space_dimension()

Because the penalty matrix is the full-rank identity I_k, every basis coefficient is penalized and there is no unpenalized null space, unlike smooths with derivative-based penalties (e.g. TPRS) that leave polynomial trends unpenalized.

Returns

int
Always 0.

penalty_matrix()

Return the (k, k) identity penalty matrix.

Usage

Source

penalty_matrix()

Returns

NDArray
The k x k identity matrix, where k is the number of retained levels. Every coefficient is penalized equally.