Skip to content

stack_proportional -- weight models by relative score, not winner-take-all - #128

Merged
jc-macdonald merged 1 commit into
mainfrom
feat/stack-proportional
Sep 1, 2026
Merged

stack_proportional -- weight models by relative score, not winner-take-all#128
jc-macdonald merged 1 commit into
mainfrom
feat/stack-proportional

Conversation

@jc-macdonald

Copy link
Copy Markdown
Collaborator

Summary

  • stack_scores() is a linear program over the simplex, so it always puts all weight on the single best-performing model whenever there's any nonzero gap -- including a gap that's just measurement noise between two genuinely near-tied models. In practice (pp-eigentest's ensemble stacking) this made weights unstable: an unrelated upstream bugfix that shifted one model's score by a hair, well within replication noise, flipped the "winner" and swung weights from an even 0.5/0.5 split to 1.0/0.0.
  • stack_proportional(score_matrix, *, maximize=False) instead scales weight smoothly with relative performance: w_m ∝ mean_score_m (inverted via max - score for minimize, so a score of exactly 0 doesn't blow up). Falls back to a uniform split when every model scores identically.

Test plan

  • ruff format --preview --check / ruff check --preview -- clean
  • mypy --strict src -- clean
  • New tests: sum-to-one, non-negative, near-tie splits smoothly (the key behavior difference from stack_scores), dominant-model ordering (both minimize/maximize), uniform fallback on ties, zero-score doesn't blow up, shape, dtype -- all pass
  • pytest (full suite) -- all pass, no regressions

…er-take-all

stack_scores() is a linear program over the simplex, so it always puts
all weight on the single best-performing model whenever there's any
nonzero gap -- including a gap that's just measurement noise between
two genuinely near-tied models. In practice this makes the resulting
weights unstable: an unrelated upstream bugfix that shifts one model's
score by a hair, well within replication noise, can flip the "winner"
and swing weights from an even split to 100/0.

stack_proportional() instead scales weight smoothly with relative
performance: w_m proportional to mean_score_m (inverted via max-score
for minimize, so a score of exactly 0 doesn't blow up). Falls back to a
uniform split when every model scores identically.
@jc-macdonald
jc-macdonald merged commit 68753ad into main Sep 1, 2026
4 checks passed
@jc-macdonald
jc-macdonald deleted the feat/stack-proportional branch September 1, 2026 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant