PSpline#

class superglm.PSpline(
n_knots: int = 10,
degree: int = 3,
knot_strategy: str = 'uniform',
penalty: str = 'ssp',
select: bool = False,
knots: ArrayLike | None = None,
discrete: bool | None = None,
n_bins: int | None = None,
extrapolation: str = 'clip',
boundary: tuple[float, float] | None = None,
knot_alpha: float = 0.2,
constraint=None,
m: int | tuple[int, ...] = 2,
lambda_policy: LambdaPolicy | dict[str, LambdaPolicy] | None = None,
)#

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 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:
n_knotsint

Number of interior knots.

degreeint

B-spline polynomial degree.

knot_strategystr

“uniform” (default), “quantile”, “quantile_rows”, or “quantile_tempered”.

penaltystr

“ssp” enables SSP reparametrisation, “none” disables it.

selectbool

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).

knotsarray-like or None

Explicit interior knot positions.

constraintConstraintSpec 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. Fit-time convexity/concavity is supported for degrees one through three; higher degrees require a Constraint.postfit.* token.