feat(sleep): paired A/B evalkit with McNemar and bootstrap CIs - #242
Open
Bogdan (Dan) Baciu (bogdanbaciu21) wants to merge 1 commit into
Open
feat(sleep): paired A/B evalkit with McNemar and bootstrap CIs#242Bogdan (Dan) Baciu (bogdanbaciu21) wants to merge 1 commit into
Bogdan (Dan) Baciu (bogdanbaciu21) wants to merge 1 commit into
Conversation
Add a stdlib evalkit so Sleep comparisons share one instrument: one fixed task manifest, McNemar on paired binary outcomes, percentile bootstrap CIs on the success-rate delta, and multi-seed variance bands. Cross-manifest id mismatches are refused. The nightly gate is unchanged. Related: microsoft#108
Contributor
Author
|
Working and running the test suite comprehensively across Linux and Mac and Windows. Will try to finish today. |
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.
Related: #108
What Problem This Solves
Resolves a problem where Sleep contributors and operators have no shared instrument for claiming condition B beats condition A: comparisons are single-run numbers on possibly different task sets, with no uncertainty reported, so sub-noise deltas are claimable and real regressions can hide.
Upstream
docs/sleep/RESULTS.mdalready warns that single-seed deltas under about 1.5 points are noise, and issue #108 asks for a single-seed versus multi-seed protocol. This PR is that instrument.Why This Change Was Made
A small stdlib
evalkitmodule runs two conditions over one fixed task manifest (paired by task id), scores per-task binary outcomes, and reports McNemar's test for the paired difference plus a percentile-bootstrap confidence interval on the success-rate delta. When each task carries same-length seed repeats, the kit also publishes per-seed deltas plus their mean and sample sd (the house answer to #108).It does not change the nightly gate. It standardizes the evidence that reports and later PRs cite. Cross-manifest comparisons are refused. Graded (non-binary) scores are bootstrap-only and require an explicit allow flag, because McNemar is not defined for them.
CLI:
Also wired as
skillopt_sleep evalkit. Built on current upstreammainatda06b15(includes #235).Project Fit
User Impact
Contributors get a one-command harness that turns an experiment into a reviewable JSON plus markdown report. Operators who never invoke it see zero change: no config keys, no gate behavior, no extra backend calls.
Proof
Before (stock
mainatda06b15):python -m skillopt_sleep.evalkitdoes not exist; there is no in-repo McNemar or bootstrap helper; RESULTS cells are quoted as point estimates.After (this pull request's commits, head
79447e311807a03639eded8fadf8d7467eb9035e):Textbook 2x2 fixture (
tests/fixtures/evalkit/mcnemar_textbook.json): both+=40, A-only=2, B-only=12, both-=46. Uncorrected chi-square is100/14 = 7.142857142857143,p_chi2 = 0.007526315166457887, two-sided exact binomialp_exact = 0.012939453125. Tests pin all three to 12 decimal places.A/A fixture (40 identical tasks): delta 0,
p_exact = 1, bootstrap CI includes 0. The A/A CLI path exits 0 on that fixture and exits 2 on mismatched ids.RESULTS replay: SearchQA / GPT-5.4-nano / gated / cumulative nights=5 (
n=1400, 0.560 to 0.679, published delta +0.119). Per-task pairs were not published, so the replay uses a documented maximum-concordance reconstruction (firstround(n * rate)tasks succeed in each condition). The harness recovers the published delta and a CI that excludes 0. It does not claim to recover the original microdata.Re-run on 2026-08-21 against this pull request's head, Linux, Python 3.12.3, after
uv venvanduv pip install -e ".[dev]":Same commands on parent
da06b15(this pull request's first parent, no evalkit):The delta is exactly the 17 new evalkit tests, with zero regressions.
A/A CLI on the shipped fixture (same environment):
Academic Support
Testing
New:
tests/test_evalkit.py, 17 tests pinning textbook McNemar, bootstrap determinism and coverage on a known shift, A/A non-rejection, mismatched/empty/duplicate id refusal, graded-score bootstrap-only path, multi-seed variance bands, RESULTS cell replay, and CLI exit codes. Full suite:uv run pytest -q(orpython -m pytest -q).Limitations & Negative Results
Reproduce It Yourself
Check out this pull request's commits and run:
Equivalent without uv:
python -m venv .venv && ./.venv/bin/python -m pip install -e ".[dev]"then the same pytest and module commands through that interpreter.