from __future__ import annotations import json import subprocess import sys import tempfile import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] class ModelComparisonTest(unittest.TestCase): def test_aligned_candidate_reports_paired_improvement(self) -> None: labels = [0, 0, 0, 0, 1, 1, 1, 1] baseline_scores = [0.1, 0.4, 0.3, 0.2, 0.3, 0.6, 0.5, 0.4] candidate_scores = [0.05, 0.10, 0.15, 0.20, 0.80, 0.85, 0.90, 0.95] with tempfile.TemporaryDirectory() as directory: root = Path(directory) baseline = root / "baseline.jsonl" candidate = root / "candidate.jsonl" output = root / "comparison.json" for path, scores in ((baseline, baseline_scores), (candidate, candidate_scores)): path.write_text( "".join( json.dumps( { "record_id": f"row-{index}", "group_id": f"group-{index}", "label": label, "probability": score, } ) + "\n" for index, (label, score) in enumerate(zip(labels, scores, strict=True)) ), encoding="utf-8", ) completed = subprocess.run( [ sys.executable, str(ROOT / "scripts/compare_models.py"), "--baseline", str(baseline), "--candidate", str(candidate), "--output", str(output), "--fpr-budget", "0.25", "--bootstrap-samples", "50", ], cwd=ROOT, check=False, capture_output=True, text=True, ) self.assertEqual(completed.returncode, 0, completed.stderr) report = json.loads(output.read_text(encoding="utf-8")) self.assertEqual(report["count"], 8) self.assertEqual(report["group_count"], 8) self.assertGreater(report["candidate_minus_baseline_95ci"]["roc_auc"]["estimate"], 0.0) self.assertEqual(report["candidate"]["metrics"]["roc_auc"], 1.0) if __name__ == "__main__": unittest.main()