Report pairwise calibration ECE for nonlinear selector
Browse files
workspace/scripts/eval_nonlinear_dominance_selector.py
CHANGED
|
@@ -36,10 +36,13 @@ from scripts.eval_learned_dominance_selector import ( # noqa: E402
|
|
| 36 |
_evaluate_predictions,
|
| 37 |
_feature_names,
|
| 38 |
_group_means,
|
|
|
|
|
|
|
| 39 |
_resolve_index_path,
|
| 40 |
_selector_chart_map,
|
| 41 |
_simple_summary,
|
| 42 |
_source_evidence_map,
|
|
|
|
| 43 |
_uses_chart_compat,
|
| 44 |
_uses_source_evidence,
|
| 45 |
)
|
|
@@ -197,11 +200,32 @@ def main(argv: list[str] | None = None) -> int:
|
|
| 197 |
seed=args.seed,
|
| 198 |
)
|
| 199 |
eval_predictions = _predict(best["model"], eval_dataset, model_type=best["model_type"])
|
| 200 |
-
eval_cases = _evaluate_predictions(eval_dataset, eval_predictions, tau=best["tau"])
|
| 201 |
fit_predictions = _predict(best["model"], fit_dataset, model_type=best["model_type"])
|
| 202 |
select_predictions = _predict(best["model"], select_dataset, model_type=best["model_type"])
|
| 203 |
-
|
| 204 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 205 |
|
| 206 |
metric_names = sorted(
|
| 207 |
{
|
|
@@ -264,9 +288,14 @@ def main(argv: list[str] | None = None) -> int:
|
|
| 264 |
"num_selection_candidates": len(select_dataset["samples"]),
|
| 265 |
"num_eval_candidates": len(eval_dataset["samples"]),
|
| 266 |
"model_selection": best["selection"],
|
| 267 |
-
"fit_summary":
|
| 268 |
-
"selection_summary":
|
| 269 |
-
"eval_summary":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
"summary": summary,
|
| 271 |
"rows": eval_cases,
|
| 272 |
}
|
|
@@ -512,15 +541,16 @@ def _table(metrics: dict[str, Any]) -> str:
|
|
| 512 |
summary = metrics["eval_summary"]
|
| 513 |
lines = [
|
| 514 |
"% Auto-generated by scripts/eval_nonlinear_dominance_selector.py",
|
| 515 |
-
"\\begin{tabular}{
|
| 516 |
"\\toprule",
|
| 517 |
-
"Rows & Coverage & Fallback & Base succ. & Selected succ. & Oracle succ. & OutcomePTR & Succ. support gap & Succ. selector gap \\\\",
|
| 518 |
"\\midrule",
|
| 519 |
f"{metrics['num_eval_rows']} & {_fmt(summary.get('coverage'))} & "
|
| 520 |
f"{_fmt(summary.get('fallback_rate'))} & {_fmt(summary.get('base_success'))} & "
|
| 521 |
f"{_fmt(summary.get('selected_success'))} & {_fmt(summary.get('proposal_oracle_success'))} & "
|
| 522 |
f"{_fmt(summary.get('outcome_ptr'))} & {_fmt(summary.get('success_support_gap'))} & "
|
| 523 |
-
f"{_fmt(summary.get('success_selector_gap'))}
|
|
|
|
| 524 |
"\\bottomrule",
|
| 525 |
"\\end{tabular}",
|
| 526 |
]
|
|
@@ -546,20 +576,23 @@ def _report(metrics: dict[str, Any]) -> str:
|
|
| 546 |
"",
|
| 547 |
"The model is fit on calibration-fit rows, and model/tau are selected on held-out calibration-selection rows only. Eval outcomes are used only for reporting.",
|
| 548 |
"",
|
| 549 |
-
"| Split | Coverage | Fallback | Base success | Selected success | Proposal oracle | OutcomePTR | Success support gap | Success selector gap |",
|
| 550 |
-
"| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |",
|
| 551 |
f"| fit | {_fmt(fit.get('coverage'))} | {_fmt(fit.get('fallback_rate'))} | "
|
| 552 |
f"{_fmt(fit.get('base_success'))} | {_fmt(fit.get('selected_success'))} | "
|
| 553 |
f"{_fmt(fit.get('proposal_oracle_success'))} | {_fmt(fit.get('outcome_ptr'))} | "
|
| 554 |
-
f"{_fmt(fit.get('success_support_gap'))} | {_fmt(fit.get('success_selector_gap'))} |"
|
|
|
|
| 555 |
f"| selection | {_fmt(selection.get('coverage'))} | {_fmt(selection.get('fallback_rate'))} | "
|
| 556 |
f"{_fmt(selection.get('base_success'))} | {_fmt(selection.get('selected_success'))} | "
|
| 557 |
f"{_fmt(selection.get('proposal_oracle_success'))} | {_fmt(selection.get('outcome_ptr'))} | "
|
| 558 |
-
f"{_fmt(selection.get('success_support_gap'))} | {_fmt(selection.get('success_selector_gap'))} |"
|
|
|
|
| 559 |
f"| eval | {_fmt(eval_summary.get('coverage'))} | {_fmt(eval_summary.get('fallback_rate'))} | "
|
| 560 |
f"{_fmt(eval_summary.get('base_success'))} | {_fmt(eval_summary.get('selected_success'))} | "
|
| 561 |
f"{_fmt(eval_summary.get('proposal_oracle_success'))} | {_fmt(eval_summary.get('outcome_ptr'))} | "
|
| 562 |
-
f"{_fmt(eval_summary.get('success_support_gap'))} | {_fmt(eval_summary.get('success_selector_gap'))} |"
|
|
|
|
| 563 |
"",
|
| 564 |
"This is a train-calibrated selector diagnostic over already measured candidates, not a new rollout.",
|
| 565 |
]
|
|
|
|
| 36 |
_evaluate_predictions,
|
| 37 |
_feature_names,
|
| 38 |
_group_means,
|
| 39 |
+
_pairwise_calibration_global,
|
| 40 |
+
_pairwise_calibration_summary,
|
| 41 |
_resolve_index_path,
|
| 42 |
_selector_chart_map,
|
| 43 |
_simple_summary,
|
| 44 |
_source_evidence_map,
|
| 45 |
+
_summary_with_pairwise,
|
| 46 |
_uses_chart_compat,
|
| 47 |
_uses_source_evidence,
|
| 48 |
)
|
|
|
|
| 200 |
seed=args.seed,
|
| 201 |
)
|
| 202 |
eval_predictions = _predict(best["model"], eval_dataset, model_type=best["model_type"])
|
|
|
|
| 203 |
fit_predictions = _predict(best["model"], fit_dataset, model_type=best["model_type"])
|
| 204 |
select_predictions = _predict(best["model"], select_dataset, model_type=best["model_type"])
|
| 205 |
+
eval_pairwise = _pairwise_calibration_summary(eval_dataset, eval_predictions)
|
| 206 |
+
fit_pairwise = _pairwise_calibration_summary(fit_dataset, fit_predictions)
|
| 207 |
+
select_pairwise = _pairwise_calibration_summary(select_dataset, select_predictions)
|
| 208 |
+
eval_cases = _evaluate_predictions(
|
| 209 |
+
eval_dataset,
|
| 210 |
+
eval_predictions,
|
| 211 |
+
tau=best["tau"],
|
| 212 |
+
include_pairwise_calibration=True,
|
| 213 |
+
pairwise_calibration=eval_pairwise,
|
| 214 |
+
)
|
| 215 |
+
fit_cases = _evaluate_predictions(
|
| 216 |
+
fit_dataset,
|
| 217 |
+
fit_predictions,
|
| 218 |
+
tau=best["tau"],
|
| 219 |
+
include_pairwise_calibration=True,
|
| 220 |
+
pairwise_calibration=fit_pairwise,
|
| 221 |
+
)
|
| 222 |
+
select_cases = _evaluate_predictions(
|
| 223 |
+
select_dataset,
|
| 224 |
+
select_predictions,
|
| 225 |
+
tau=best["tau"],
|
| 226 |
+
include_pairwise_calibration=True,
|
| 227 |
+
pairwise_calibration=select_pairwise,
|
| 228 |
+
)
|
| 229 |
|
| 230 |
metric_names = sorted(
|
| 231 |
{
|
|
|
|
| 288 |
"num_selection_candidates": len(select_dataset["samples"]),
|
| 289 |
"num_eval_candidates": len(eval_dataset["samples"]),
|
| 290 |
"model_selection": best["selection"],
|
| 291 |
+
"fit_summary": _summary_with_pairwise(fit_cases, fit_pairwise),
|
| 292 |
+
"selection_summary": _summary_with_pairwise(select_cases, select_pairwise),
|
| 293 |
+
"eval_summary": _summary_with_pairwise(eval_cases, eval_pairwise),
|
| 294 |
+
"pairwise_causal_calibration": {
|
| 295 |
+
"fit": _pairwise_calibration_global(fit_pairwise),
|
| 296 |
+
"selection": _pairwise_calibration_global(select_pairwise),
|
| 297 |
+
"eval": _pairwise_calibration_global(eval_pairwise),
|
| 298 |
+
},
|
| 299 |
"summary": summary,
|
| 300 |
"rows": eval_cases,
|
| 301 |
}
|
|
|
|
| 541 |
summary = metrics["eval_summary"]
|
| 542 |
lines = [
|
| 543 |
"% Auto-generated by scripts/eval_nonlinear_dominance_selector.py",
|
| 544 |
+
"\\begin{tabular}{lrrrrrrrrr}",
|
| 545 |
"\\toprule",
|
| 546 |
+
"Rows & Coverage & Fallback & Base succ. & Selected succ. & Oracle succ. & OutcomePTR & Succ. support gap & Succ. selector gap & Cal. ECE \\\\",
|
| 547 |
"\\midrule",
|
| 548 |
f"{metrics['num_eval_rows']} & {_fmt(summary.get('coverage'))} & "
|
| 549 |
f"{_fmt(summary.get('fallback_rate'))} & {_fmt(summary.get('base_success'))} & "
|
| 550 |
f"{_fmt(summary.get('selected_success'))} & {_fmt(summary.get('proposal_oracle_success'))} & "
|
| 551 |
f"{_fmt(summary.get('outcome_ptr'))} & {_fmt(summary.get('success_support_gap'))} & "
|
| 552 |
+
f"{_fmt(summary.get('success_selector_gap'))} & "
|
| 553 |
+
f"{_fmt(summary.get('pairwise_causal_calibration_ece'))} \\\\",
|
| 554 |
"\\bottomrule",
|
| 555 |
"\\end{tabular}",
|
| 556 |
]
|
|
|
|
| 576 |
"",
|
| 577 |
"The model is fit on calibration-fit rows, and model/tau are selected on held-out calibration-selection rows only. Eval outcomes are used only for reporting.",
|
| 578 |
"",
|
| 579 |
+
"| Split | Coverage | Fallback | Base success | Selected success | Proposal oracle | OutcomePTR | Success support gap | Success selector gap | Calibration ECE |",
|
| 580 |
+
"| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |",
|
| 581 |
f"| fit | {_fmt(fit.get('coverage'))} | {_fmt(fit.get('fallback_rate'))} | "
|
| 582 |
f"{_fmt(fit.get('base_success'))} | {_fmt(fit.get('selected_success'))} | "
|
| 583 |
f"{_fmt(fit.get('proposal_oracle_success'))} | {_fmt(fit.get('outcome_ptr'))} | "
|
| 584 |
+
f"{_fmt(fit.get('success_support_gap'))} | {_fmt(fit.get('success_selector_gap'))} | "
|
| 585 |
+
f"{_fmt(fit.get('pairwise_causal_calibration_ece'))} |",
|
| 586 |
f"| selection | {_fmt(selection.get('coverage'))} | {_fmt(selection.get('fallback_rate'))} | "
|
| 587 |
f"{_fmt(selection.get('base_success'))} | {_fmt(selection.get('selected_success'))} | "
|
| 588 |
f"{_fmt(selection.get('proposal_oracle_success'))} | {_fmt(selection.get('outcome_ptr'))} | "
|
| 589 |
+
f"{_fmt(selection.get('success_support_gap'))} | {_fmt(selection.get('success_selector_gap'))} | "
|
| 590 |
+
f"{_fmt(selection.get('pairwise_causal_calibration_ece'))} |",
|
| 591 |
f"| eval | {_fmt(eval_summary.get('coverage'))} | {_fmt(eval_summary.get('fallback_rate'))} | "
|
| 592 |
f"{_fmt(eval_summary.get('base_success'))} | {_fmt(eval_summary.get('selected_success'))} | "
|
| 593 |
f"{_fmt(eval_summary.get('proposal_oracle_success'))} | {_fmt(eval_summary.get('outcome_ptr'))} | "
|
| 594 |
+
f"{_fmt(eval_summary.get('success_support_gap'))} | {_fmt(eval_summary.get('success_selector_gap'))} | "
|
| 595 |
+
f"{_fmt(eval_summary.get('pairwise_causal_calibration_ece'))} |",
|
| 596 |
"",
|
| 597 |
"This is a train-calibrated selector diagnostic over already measured candidates, not a new rollout.",
|
| 598 |
]
|