mixle.evolve.verify module¶
The champion/challenger gate: “did the challenger SIGNIFICANTLY beat the champion, no regression?”
This is the single decision rule the whole loop turns on, and the anti-regression guarantee lives here. It is pure glue over existing statistics – it owns the policy (alpha, the effect-size floor, the calibration no-regression rule, multiplicity) and never edits the underlying tests:
Paired significance –
mixle.inference.model_comparison.paired_score_difference()on the objective’s per-observation vectors, scored from the same held-out batch in the same order.Pairing integrity – both vectors are required to have equal length (they are produced from one
dataargument, so the order cannot diverge); a mismatch is a hard error, not a silent skip.Effect-size floor –
|mean_diff| >= min_effect; a statistically significant but practically negligible win does not promote.Non-nested cross-check – for family swaps (
nonnested=True) the challenger must additionally winvuong_test()andclarke_test()(BIC-corrected) on the pointwise log-likelihoods.ELPD band – when LOO/WAIC pointwise arrays are supplied,
compare_elpd()’s 2-SE band is the conservative tie rule.Calibration no-regression – a more-accurate-but-less-calibrated challenger is refused: its calibration scalar must not exceed the champion’s by
calib_tol.Multiplicity – when many challengers are tested at once,
multiplicityadjustsalphaviamixle.inference.multiple_testing.adjust_pvalues()before the gate.
- class Verdict(favored, delta, p_value, ci, calibrated, evidence=<factory>)[source]
Bases:
objectThe outcome of a single champion/challenger comparison.
- Parameters:
- favored: str
- delta: float
- p_value: float
- calibrated: bool
- evidence: dict
- property promote: bool
True iff the challenger is favored and passed calibration – the promotion predicate.
- challenger_beats_champion(champion, challenger, data, *, objective, alpha=0.05, min_effect=0.0, require_calibration=True, nonnested=False, multiplicity=None, calib_tol=1.0e-3, seed=0, elpd_pointwise=None)[source]
Decide whether
challengersignificantly and non-regressively beatschampionondata.- Parameters:
champion (Any) – two fitted models scored on the same held-out
data.challenger (Any) – two fitted models scored on the same held-out
data.data (Any) – the held-out responses (one batch -> both models scored in the same order).
objective (Objective) – the
Objectiveto compare on.alpha (float) – significance level for the paired test (and the CI is at
1 - alpha).min_effect (float) – practical effect-size floor on
|mean score difference|.require_calibration (bool) – if True, run the calibration no-regression check.
nonnested (bool) – if True (a family swap), additionally require Vuong + Clarke to favor the challenger.
multiplicity (str | None) –
Noneor amixle.inference.multiple_testing.adjust_pvalues()method ('bonferroni'/'bh'/ …) when this is one of many simultaneous challengers – adjusts the p-value before the gate.calib_tol (float) – tolerance on the calibration-error increase the challenger may carry.
seed (int) – RNG seed for the (sampled) calibration scalars.
elpd_pointwise (tuple[ndarray, ndarray] | None) – optional
(pointwise_champion, pointwise_challenger)LOO/WAIC arrays; when given, thecompare_elpd()2-SE band is required to also favor the challenger.
- Returns:
A
Verdict.verdict.promoteis the single promotion predicate.- Return type:
Verdict