Repository navigation
Add matrix-free multinomial solver, prediction guardrails, and monotone spline interactions - #35
Merged
Conversation
Multinomial: opt-in solver="matrix_free_cg" (diagonally preconditioned Newton-CG via Hessian-vector products, no dense Hessian assembly), with solver="auto" falling back to it when the dense guards reject the fit. Results expose solver_name and matrix_free_cg_iterations. GLM predict(): response_ceiling="auto" guardrail caps unbounded-mean families (Poisson, Gamma, Tweedie, negbinomial) at 10x the largest observed training response, so runaway extrapolation cannot silently dominate deviance-based scores. Review hardening on top of the original work: - warn when the auto ceiling engages; never truncate silently - internal consumers (complement offsets, compute_loss, calibration, diagnostics) score the true mean via response_ceiling=None - persist response_scale in to_bytes/from_bytes so save/load does not change default predict() behavior - floor the null-deviance sub-fit's dense guards at q=K-1 so a converged matrix-free fit cannot fail at the null-deviance stage - fail fast on matrix_free_cg + lasso/sign-constraints/covariance in the CV path instead of swallowing per-fold errors into alpha=0, and keep the dense CV preflight for solver="auto" when the final refit must compute covariance - dedup the CG non-convergence warning, gate the sparse row cache on the dense solver, share one Newton-loop convergence contract - update the stale monotonicity test: the alpha>0 smooth path now enforces monotone constraints via fixed lambda=alpha D'D penalties Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
predict() stays the honest inverse-link by default: a pricing library must not alter numeric outputs across an upgrade, capped values look plausible while runaway ones look broken, and the pathological tail is already fail-closed by on_extreme_eta="raise". Scoring pipelines that want the extrapolation cap opt in with response_ceiling="auto" (10x max observed training response, warns on engagement) or an explicit float. Internal consumers keep pinning response_ceiling=None explicitly. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rix-free-guardrails
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Raises the Python coverage back over the 97% CI gate by testing the paths 33dcea5 introduced without tests: fit_diagnostics, the per-family prediction deviance rows in predict_diagnostics (poisson/gamma/binomial/ tweedie/gaussian + validation), the on_extreme_eta="warn" policy, complement overrides (column and model+exposure) at predict time, spline df=/k= spec parsing, CV path-info properties, and the multinomial CV lasso classification. Writing the explore() test caught a real bug: the array-exposure branch raised NameError because formula.py uses function-local polars imports and explore() was missing its own. Fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The explore() coverage test ran explore_data in the repo root, whose documented auto-save overwrote analysis/exploration.json; the test now chdirs into tmp_path, and the artifact is restored to its prior state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eview Interaction splines (shipped broken in v0.8.16): - interaction-local spline specs no longer clobber a same-named main-effect spline (registry and basis caches are context-scoped), fixing predict crashes under divergent widths and silent mis-scoring under same-width divergent specs - monotone smooth x categorical blocks now encode one OWN curve per category (full-k, category-major) instead of k-1 sign-constrained deviations, which forced every category at/above the reference and fitted true negative category gaps as zero; the categorical main effect is required for free per-category levels (fails closed otherwise) - monotone smooths and D'D penalties are now honored with continuous co-factors (the constraint governs the spline function f itself) and in pure continuous x spline interactions; previously both were silently dropped - fail closed on the remaining unsupported shapes: monotone fixed-df splines in interactions, multi-categorical monotone interactions, and monotone tensor-product smooths - serialization schema bumped to 5; v4 blobs are rejected with a targeted error (v0.8.15 and v0.8.16 wrote incompatible cat x spline layouts under the same version number) Guardrail/diagnostics defects (unreleased, from 33dcea5): - diagnostics() clips extreme eta at its internal predict calls instead of dying on the pathological models it exists to inspect - predict_diagnostics deviance rows use the Rust unit-deviance helper with the model's var_power/theta embedded (negbinomial rows were scored with the Poisson formula) - the 2000-iteration monotone budget applies on the alpha>0 fixed-penalty route too (was 25) - on_extreme_eta/eta_clip are validated on every link, not only log - fit() documents the alpha>0 smooth-route semantics (parametric columns unpenalized, standardize not applied) Every fix carries a regression test mirroring the review verifiers' reproductions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI exposed platform-dependent monotonicity violations (0.09-0.12 on ubuntu/windows BLAS, clean on macOS): with include_main=True the main x-smooth overlapped the full-k per-category curves, and the free split between the two sequence-constrained components does not compose into a function-level monotonicity guarantee. The per-category curves already nest any common component, so the redundant same-variable main spline is now rejected with an instructive error, making per-category monotonicity rest on the solver's per-block guarantee alone — a 12-seed x 3-category sweep shows exactly zero violation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rolls up the insur-arena work stream since v0.8.15, in three layers:
488fd1f): monotone/smooth spline terms inside interaction terms — interaction-local spline specs, category-major basis ordering, and per-category smooth constraint blocks.33dcea5):predict()fails closed on extreme linear predictors (on_extreme_eta="raise", override with"clip"/"warn");alpha > 0with smooth terms routes to the fixed λ=α D'D penalty solver and enforces monotonicity (previously scalar ridge + a warning); L1/elastic-net with smooth terms now raises.66cfe38,967733d): opt-insolver="matrix_free_cg"(diagonally preconditioned Newton-CG via Hessian-vector products, no dense Hessian) withsolver="auto"fallback andsolver_name/matrix_free_cg_iterationsreporting; opt-inpredict(response_ceiling=...)extrapolation cap ("auto"= 10x max observed training response, warns on engagement, persisted across serialization).The final layer includes fixes for all 10 confirmed findings from a 33-agent adversarial review: uncapped internal consumers (complement offsets, loss, calibration, diagnostics), serialized
response_scale, null-deviance dense-guard floor, CV fail-fast preflight for matrix-free incompatibilities, CG warning dedup, sparse-cache gating, shared Newton-loop convergence contract, and.pyistub sync.Behavior changes vs 0.8.15 (release-notes material)
predict()raisesPredictionErroron |eta| > 50 by default instead of returning overflow-scale means.alpha > 0+ smooth terms: monotonicity is now enforced via the fixed-penalty smooth path (fitted coefficients change for smooth+ridge fits);l1_ratio > 0+ smooth terms now errors.response_ceilingdefaults toNone; multinomialsolverdefaults to"dense".Suggested release: 0.9.0 (minor, for the default-behavior changes above).
Testing
-D warningsclean; 833 Rust tests pass (2 new regression tests)🤖 Generated with Claude Code