Skip to content

Features

Feature specs define how raw columns become model terms. This page keeps the public Spline(...) factory separate from the concrete feature classes so the API reads in the same order users encounter it.

Factory

Spline(...) is the public entry point for spline specs. Use kind="ps" for a difference-penalized P-spline and kind="bs" for an integrated-derivative B-spline smooth.

Use constraint= to request monotone or curvature-constrained fits:

  • Constraint.fit.increasing
  • Constraint.fit.decreasing
  • Constraint.fit.convex
  • Constraint.fit.concave
  • Constraint.postfit.increasing
  • Constraint.postfit.decreasing
  • Constraint.postfit.convex
  • Constraint.postfit.concave

These constraints are interpreted on the spline term's contribution to the linear predictor. For non-identity links, that means the constrained object is the term on the eta scale, not the back-transformed response mean.

Fit-time engine selection depends on the concrete spline class:

Feature spec Fit-time constraints Engine fit_reml() automatic lambda behavior
PSpline(..., constraint=Constraint.fit.increasing/decreasing/convex/concave) monotone + curvature SCOP integrated constrained REML / EFS
BSplineSmooth(..., constraint=Constraint.fit.increasing/decreasing/convex/concave) monotone + curvature QP unconstrained REML followed by constrained refit at those lambdas
CubicRegressionSpline(..., constraint=Constraint.fit.increasing/decreasing/convex/concave) monotone + curvature QP unconstrained REML followed by constrained refit at those lambdas

Constraint.postfit.* keeps the unconstrained fit and applies a repair later with model.apply_shape_postfit(...).

Spline(kind='ps', *, k=None, n_knots=None, degree=3, knot_strategy='uniform', penalty='ssp', select=False, knots=None, discrete=None, n_bins=None, extrapolation='clip', boundary=None, knot_alpha=0.2, constraint=None, m=2, lambda_policy=None)

Create a spline feature spec.

Spline Classes

PSpline

Bases: _BSplineBase

P-spline: B-spline basis with a discrete-difference penalty.

This is the concrete P-spline implementation. For the recommended public API, use :func:Spline which dispatches to PSpline, NaturalSpline, or CubicRegressionSpline based on kind.

The m parameter controls the discrete difference order(s) for the penalty (default 2, second-difference).

Parameters:

Name Type Description Default
n_knots int

Number of interior knots.

10
degree int

B-spline polynomial degree.

3
knot_strategy str

"uniform" (default), "quantile", "quantile_rows", or "quantile_tempered".

'uniform'
penalty str

"ssp" enables SSP reparametrisation, "none" disables it.

'ssp'
select bool

If True, decompose the spline into null-space (linear) and range-space (wiggly) subgroups for three-way selection: nonlinear -> linear -> dropped.

Double penalty: The null-space (linear) subgroup is penalised with a ridge penalty (penalty_matrix=eye(1)). With fit_reml(), REML estimates separate lambdas for the linear and spline subgroups — driving the linear lambda to infinity effectively zeros the linear component (three-way selection: nonlinear -> linear -> dropped). See Wood (2011).

False
knots array - like or None

Explicit interior knot positions.

None
constraint ConstraintSpec or None

Public shape-constraint token. Use Constraint.fit.increasing, Constraint.fit.decreasing, Constraint.fit.convex, Constraint.fit.concave, Constraint.postfit.increasing, Constraint.postfit.decreasing, Constraint.postfit.convex, or Constraint.postfit.concave. For PSpline, fit-time shape constraints apply on the spline term's linear-predictor contribution and use the SCOP engine. This works in both exact and discrete=True fitting paths. With fit_reml(), fixed lambdas work directly and automatic lambda estimation uses the dedicated shape-aware SCOP REML / EFS path.

None

BSplineSmooth

Bases: _BSplineBase

B-spline smooth: B-spline basis with an integrated-derivative penalty.

Same raw B-spline basis as PSpline, but penalised via the integrated squared m-th derivative rather than the discrete difference penalty. This is the analogue of mgcv's "bs" smooth.

The penalty matrix is::

omega_ij = int B_i^(m)(x) B_j^(m)(x) dx

computed by Gauss--Legendre quadrature over each knot span. m is the integrated derivative order (default 2 = integrated second-derivative penalty). Compare with PSpline where m is the finite-difference order on the coefficient vector.

Cubic by default (degree=3) but general degree is allowed.

Parameters:

Name Type Description Default
n_knots int

Number of interior knots.

10
degree int

B-spline polynomial degree.

3
knot_strategy str

"uniform" or "quantile".

'uniform'
penalty str

"ssp" enables SSP reparametrisation, "none" for raw.

'ssp'
select bool

If True, add double-penalty shrinkage (null + range space).

False
knots array - like or None

Explicit interior knot positions.

None
constraint ConstraintSpec or None

Public shape-constraint token. Use Constraint.fit.increasing, Constraint.fit.decreasing, Constraint.fit.convex, Constraint.fit.concave, Constraint.postfit.increasing, Constraint.postfit.decreasing, Constraint.postfit.convex, or Constraint.postfit.concave. For BSplineSmooth, fit-time monotone and curvature constraints apply on the spline term's linear-predictor contribution and use the constrained QP solver path. With fit_reml(), fixed lambdas work directly; automatic lambda estimation uses the QP passthrough heuristic (unconstrained REML followed by constrained refit), not exact joint constrained REML.

None
m int or tuple of int

Integrated derivative order(s) for the penalty.

2
lambda_policy LambdaPolicy or dict or None

Per-component lambda control.

None

NaturalSpline

Bases: _SplineBase

Natural P-spline: f''=0 at boundaries, linear tails.

Applies natural boundary constraints: f''(boundary) = 0 at both ends. The underlying basis therefore has linear tails beyond the boundary knots, preventing the tail explosions common with unconstrained B-splines. Prediction behavior outside the training range is then controlled by extrapolation: "clip" (default) freezes at the boundary, while "extend" exposes the linear tails.

Uses a second-difference penalty (like BS) rather than the integrated-f'' penalty of CubicRegressionSpline. The boundary constraints reduce the penalty null space to 1 dimension (constant only), so select=True is not supported — use kind="cr" or kind="ps" for double-penalty selection.

CubicRegressionSpline

Bases: _SplineBase

CR spline: integrated f'' squared penalty + natural boundary constraints.

Compatible with the standard cubic regression spline construction used in GAM packages. Always cubic (degree=3). Natural boundary constraints (f''=0 at boundaries) are mandatory. The basis has linear tails, but default prediction still clips at the training boundary unless extrapolation="extend" is used.

The penalty matrix is the wiggliness penalty: omega_ij = int B_i''(x) B_j''(x) dx, computed via Gauss-Legendre quadrature over each knot interval.

Multi-order penalties (m tuple) are a SuperGLM extension, not strict mgcv bs="cr" parity.

Parameters:

Name Type Description Default
constraint ConstraintSpec or None

Public shape-constraint token. Use Constraint.fit.increasing, Constraint.fit.decreasing, Constraint.fit.convex, Constraint.fit.concave, Constraint.postfit.increasing, Constraint.postfit.decreasing, Constraint.postfit.convex, or Constraint.postfit.concave. For CubicRegressionSpline, fit-time monotone and curvature constraints apply on the spline term's linear-predictor contribution and use the constrained QP solver path. With fit_reml(), fixed lambdas work directly; automatic lambda estimation uses the QP passthrough heuristic (unconstrained REML followed by constrained refit), not exact joint constrained REML.

None

Other Feature Classes

Categorical

One-hot encoded categorical feature.

Parameters:

Name Type Description Default
base str

How to choose the reference level. 'most_exposed' - level with highest total sample_weight (default, best for insurance) 'first' - alphabetically first level Or pass a specific level name as a string.

'most_exposed'

build(x, sample_weight=None)

Build sparse one-hot design columns, choosing the base level from x.

transform(x)

One-hot encode using levels learned during build().

score(x, beta)

Score the fitted categorical contribution directly on new data.

reconstruct(beta)

Coefficients -> relativity table.

Numeric

A single continuous feature used as-is.

Group lasso on a size-1 group = standard L1 soft-thresholding. The column is passed through without any transformation.

build(x, sample_weight=None)

Build a single-column design matrix.

transform(x)

Transform new data (pass-through).

score(x, beta)

Score the fitted numeric contribution directly on new data.

reconstruct(beta)

Reconstruct the coefficient on the original scale.

Polynomial

Orthogonal polynomial feature (Legendre basis).

Scales x to [-1, 1] using training-data min/max, then builds a Legendre polynomial basis of degrees 1 through degree (the degree-0 constant is excluded — the model intercept handles it).

Group size = degree.

Parameters:

Name Type Description Default
degree int

Maximum polynomial degree. 2 (quadratic) or 3 (cubic) are the standard insurance choices. Higher values are allowed but rarely useful.

3

build(x, sample_weight=None)

Build Legendre basis columns after learning min/max from x.

transform(x)

Scale x using fitted min/max and return the Legendre basis matrix.

score(x, beta)

Score the fitted polynomial contribution directly on new data.

reconstruct(beta, n_points=200)

Evaluate the fitted polynomial on a grid and return relativities.