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.increasingConstraint.fit.decreasingConstraint.fit.convexConstraint.fit.concaveConstraint.postfit.increasingConstraint.postfit.decreasingConstraint.postfit.convexConstraint.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 ( |
False
|
knots
|
array - like or None
|
Explicit interior knot positions. |
None
|
constraint
|
ConstraintSpec or None
|
Public shape-constraint token. Use |
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'
|
penalty
|
str
|
|
'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 |
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 |
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.
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.