evalstats 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. {evalstats-0.2.2 → evalstats-0.2.4}/PKG-INFO +53 -38
  2. {evalstats-0.2.2 → evalstats-0.2.4}/README.md +52 -37
  3. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/__init__.py +1 -1
  4. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/alignment.py +255 -11
  5. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/api.py +99 -27
  6. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/cli.py +13 -0
  7. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/config.py +84 -21
  8. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/bundles.py +7 -0
  9. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/paired.py +221 -13
  10. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/ranking.py +15 -1
  11. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/resampling.py +684 -70
  12. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/router.py +93 -13
  13. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/stats_utils.py +89 -2
  14. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/summary.py +71 -53
  15. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/types.py +1 -0
  16. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/variance.py +28 -2
  17. evalstats-0.2.4/evalstats/ppi.py +941 -0
  18. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/tests/__init__.py +1414 -143
  19. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/PKG-INFO +53 -38
  20. {evalstats-0.2.2 → evalstats-0.2.4}/pyproject.toml +1 -1
  21. evalstats-0.2.4/tests/test_auto_ci_routing.py +317 -0
  22. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_bayes_binary_routing.py +5 -5
  23. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_cli.py +30 -6
  24. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_ppi_corrections.py +266 -72
  25. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_simultaneous_ci.py +252 -0
  26. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_wilson_newcombe.py +2 -2
  27. evalstats-0.2.2/evalstats/ppi.py +0 -375
  28. evalstats-0.2.2/tests/test_auto_ci_routing.py +0 -197
  29. {evalstats-0.2.2 → evalstats-0.2.4}/LICENSE +0 -0
  30. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/__init__.py +0 -0
  31. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/bayes_evals.py +0 -0
  32. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/core/mixed_effects.py +0 -0
  33. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/io.py +0 -0
  34. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/loader.py +0 -0
  35. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/__init__.py +0 -0
  36. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/critical_difference.py +0 -0
  37. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/forest.py +0 -0
  38. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/heatmap.py +0 -0
  39. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/point_estimates.py +0 -0
  40. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats/vis/scoreboard.py +0 -0
  41. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/SOURCES.txt +0 -0
  42. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/dependency_links.txt +0 -0
  43. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/entry_points.txt +0 -0
  44. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/requires.txt +0 -0
  45. {evalstats-0.2.2 → evalstats-0.2.4}/evalstats.egg-info/top_level.txt +0 -0
  46. {evalstats-0.2.2 → evalstats-0.2.4}/setup.cfg +0 -0
  47. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_alignment.py +0 -0
  48. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_analyze.py +0 -0
  49. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_analyze_factorial.py +0 -0
  50. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_bootstrap_t_pairwise_ranking.py +0 -0
  51. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_compare.py +0 -0
  52. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_critical_difference_plot.py +0 -0
  53. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_io.py +0 -0
  54. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_lmm.py +0 -0
  55. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_lmm_backend_parity.py +0 -0
  56. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_lmm_statsmodels.py +0 -0
  57. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_nig_ci_methods.py +0 -0
  58. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_p_values.py +0 -0
  59. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_permutation.py +0 -0
  60. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_ppi_core.py +0 -0
  61. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_resampling.py +0 -0
  62. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_scoreboard_plot.py +0 -0
  63. {evalstats-0.2.2 → evalstats-0.2.4}/tests/test_set_alpha_ci.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evalstats
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Statistically sane analysis methods for comparing AI model and prompt performance.
5
5
  Author: Ian Arawjo
6
6
  License-Expression: MIT
@@ -54,7 +54,7 @@ Dynamic: license-file
54
54
 
55
55
  # evalstats
56
56
 
57
- Utilities and guidance for statistically sane analyses for comparing prompt and LLM performance. Compute statistics and visualize the results.
57
+ Rigorous statistical analysis for LLM evaluations, from model and prompt comparisons to statistical tests resilient to LLM judge bias, including in small sample data regimes.
58
58
 
59
59
  `evalstats` helps you answer questions like:
60
60
  - Is Prompt A actually better than Prompt B, or just slightly luckier on this dataset?
@@ -62,20 +62,29 @@ Utilities and guidance for statistically sane analyses for comparing prompt and
62
62
  - How sensitive is model performance to prompt wording?
63
63
  - Are my performance differences large enough to be meaningful, or just noise?
64
64
  - How stable are scores across runs, evaluators, or inputs?
65
- - What statistics test should I run in X situation?
65
+ - Can I trust my LLM-judge scores, or do they need correcting against human labels first?
66
66
 
67
- The idea is simple: you give `evalstats` your benchmark data, and it runs statistically appropriate analyses that quantify uncertainty and provide confidence bounds on your claims. Datasets can include eval scores, prompts, inputs, evaluator names, and (optionally) models. `evalstats` provides:
68
- - Plots and tests comparing prompt performance, with bootstrapped CIs and variance
69
- - Plots and tests comparing model performance across prompt variations
70
- - Constraints that guide you into performing best practices, like always considering prompt sensitivity when benchmarking model performance
67
+ You give `evalstats` your benchmark data, and it runs statistically appropriate analyses that quantify uncertainty and provide confidence bounds on your claims. It does this in two main ways:
71
68
 
72
- As well, there is a "learning" guide in `website/` which I am building out.
73
- This will include simulation- and research-backed examples of statistics for LLM evals,
74
- as well as example code (which will, obviously, tend to use `evalstats`, but
75
- the lessons hold regardless of implementation).
69
+ - **Comparisons**: Comparing models, prompts, or both at once (or any other thing you're comparing, like agent harnesses), and get 95% confidence intervals, pairwise significance tests, and multi-run sensitivity analyses. `evalstats` guides you toward best practices and choose well-calibrated methods and procedures by default, backed by simulations, and was built specifically to fill the gap of statistical knowledge for small-sample size datasets N<100; it will output stats as long as there are at least 15 samples. See [Statistics](#statistics).
70
+ - **PPI-corrected inference**: using a small set of human labels to correct bias in noisy LLM-judge scores, so your means, confidence intervals, and hypothesis tests p-values are accurately calibrated in the face of LLM judge bias. This builds on prediction-powered inference (PPI). See [PPI-Corrected Inference](#ppi-corrected-inference-means-cis-and-tests).
71
+
72
+ In particular, scientists can use our PPI-corrected statistical tests to analyze data for **mixed human-AI subject studies**, where some observations are human-labeled and the rest are graded by an LLM judge. Use `evalstats.tests` directly for LLM-judge-bias-corrected versions of:
73
+
74
+ - t-test (`ttest`, independent or paired; Welch's by default, or Student's equal-variance via `equal_var=True`)
75
+ - Mann–Whitney U (`mannwhitney`)
76
+ - Wilcoxon signed-rank (`wilcoxon`)
77
+ - One-way ANOVA (`anova_oneway`, independent or repeated-measures)
78
+ - Friedman test (`friedman`, repeated-measures rank-based)
79
+ - Kruskal-Wallis (`kruskalwallis`, independent-groups rank-based)
80
+
81
+ As long as the items for human labeling were sampled at random from the full dataset, p-values will stay calibrated even when the LLM judge is biased or miscalibrated. These corrections are validated via extensive Monte Carlo simulations (see `simulations/harness`). To the best of our knowledge, `evalstats` provides the only known implementations of PPI-corrected rank-based nonparametric tests like Wilcoxon.
82
+
83
+ As well,
76
84
 
77
85
  > [!IMPORTANT]
78
86
  > We are actively building out this project, both the website/guide and the package.
87
+ > Aside from the package itself, there is a "learning" guide in `website/` which I am building out and will return to after writing up the simulations. This will include simulation- and research-backed examples of statistics for LLM evals, as well as example code (which will, obviously, use `evalstats`, but the lessons hold regardless of implementation).
79
88
  > If there's something you'd like to see, or guidance on a specific topic, let us know
80
89
  > by raising an Issue.
81
90
 
@@ -270,6 +279,19 @@ would have gotten from a fully human-labeled study (Angelopoulos et al., 2023).
270
279
  Most PPI correction methods use PPIBoot (bootstrap variant of PPI; Zrnic, 2024).
271
280
  Implemented corrections have been battle-tested via simulations (see `simulations/sim_type_i_calibration.py`).
272
281
 
282
+ > **Important: which items get a human label must be chosen uniformly at
283
+ > random.** PPI correction assumes the labeled subset is representative of
284
+ > the full dataset. If your labeling process instead targets specific items
285
+ > — e.g. "always double-check the borderline or highest-scoring responses,"
286
+ > a common real-world review habit — that's missing-not-at-random (MNAR)
287
+ > selection on the outcome, and PPI correction can stay badly miscalibrated
288
+ > **no matter how many items you label**. This isn't ordinary small-sample
289
+ > noise that more labels fixes; it was confirmed in simulation to persist
290
+ > from 15 up through 300 labeled items out of 400. See
291
+ > `evalstats.ppi.correct`'s docstring for the full analysis. If you can't
292
+ > guarantee random labeling, treat any PPI-corrected result here with
293
+ > caution regardless of the reported CI/p-value.
294
+
273
295
  ### Example: Comparing models with corrected LLM judge evals via `compare(..., alignment=...)`
274
296
 
275
297
  ```python
@@ -495,36 +517,29 @@ pip install "evalstats[lmm]"
495
517
 
496
518
  Installation details may differ on your system.
497
519
 
498
- ## Future and TODO
499
-
500
- We aim to continue to contribute to `evalstats`. Ideas for future features:
501
- - Mixed-effects models (LMMs and potentially GLMMs) for multi-input data. Currently, `evalstats` only supports the case of one input per prompt template, rather than a grid search (cross product) of different prompt variations.
502
- - A default "report" mode that outputs a PDF summarizing findings and diving into the details
503
- - Integration with ChainForge as a front-end, to bring statistical analyses to plotted evals
504
- - Help developers quantify the "semantic variance" of the provided prompt templates, and perhaps even factor this into the calculation in an intelligent way. This is important because the current implementation doesn't know about the diversity/representativity of the input dataset and prompts.
505
- - Automatic "reliability" checking that generates minor prompt variations (e.g., lightly paraphrasing) and tests model robustness to small deviations. Implement various methods for generating minor prompt variations.
506
-
507
- Another area of concern, but separate from the current focus on running stats over benchmarking scores, is helping users improve their eval and test set validity. Benchmark validity testing could use diagnostic tools from Item Response Theory, to converge on a smaller, higher-quality item set where every item is valuable (e.g., see Fluid Benchmarking). For each item in a set, know:
508
- - Difficulty: What proportion of model/prompt variants get this right? Near-zero items either have bad reference answers, are genuinely unanswerable, or represent a capability so far out of range it's not discriminating anything useful. Near-ceiling items inflate scores without adding signal.
509
- - Discrimination: Does performance on this item correlate with performance on the rest of the eval? A good item should be passed by models that do well overall and failed by models that do poorly. Low or negative discrimination is a red flag. Negative discrimination especially suggests the item may be flawed, ambiguous, or testing something orthogonal.
510
-
511
- More practically speaking, we could:
512
- - Flag always-pass and always-fail items for removal or replacement. Replace them with items at a similar difficulty level to what the user intended but with better discriminating power.
513
- - Flag negative-discrimination items for inspection. These usually have one of a few problems: ambiguous wording where reasonable models disagree on interpretation, a flawed reference answer, or the item is actually measuring a different construct than the rest of the eval. Decide whether to fix or drop.
514
- - Cluster items by similarity, either by topic or by response pattern (items that all the same models pass/fail together). Prune to the most discriminating items in each cluster. After pruning, look for construct areas that lost too many items: the user may need to write better items for that region rather than leaving it underrepresented.
515
- - Benchmark distillation: Using an IRT-style approach similar to Fluid Benchmarking to find the most informative subset of eval items, and removing less informative ones. Could offer multiple methods for this, and simulations showing how they perform. E.g.:
516
- - ```
517
- Full benchmark: 1200 items
518
- Distilled benchmark: 35 items
519
- Token savings: 96%
520
- Rank correlation: 0.94
521
- ```
522
- - Target a difficulty distribution: a well-designed benchmark has items spread across the difficulty range, with more items in the middle (where models are actually differentiated) than at the extremes. If the user's distribution is skewed too easy or hard, help them write targeted items to fill gaps.
523
-
524
- ## Development
520
+ ## Reproducibility: Monte Carlo simulations
521
+
522
+ Claims in this README like "verified in our simulations" are backed by a runnable simulation harness in `simulations/harness/` of this package. We engineered these simulations so that you can run these yourself. For instance:
523
+
524
+ ```bash
525
+ python -m simulations.harness.cli --list-cases
526
+ python -m simulations.harness.cli --official-tests
527
+ python -m simulations.harness.cli ci_single --reps 50 --sizes 10 20
528
+ python -m simulations.harness.cli pvalues --mode ppi --tests ttest wilcoxon anova_rep
529
+ ```
530
+
531
+ `--official-tests will bring up a CLI with options to run specific tests. Each runs each case's canonical, full-scale preset and writes results plus a `manifest.json` (args, output paths, key metrics, pass/fail) to `simulations/out/official_<timestamp>/`. See [`simulations/harness/README.md`](simulations/harness/README.md) for the full case list, scenario library, and verification methodology against the original standalone scripts. Note that *each* simulation can take *very long* to run; even on a MacBook Pro with an M4 Max chip and 64GB RAM, with computation paralellized across 16 CPU cores, it often takes many hours.
532
+ - `ci_single` / `ci_paired` — coverage and width of confidence interval methods (bootstrap, smoothed bootstrap, Bayesian, Wilson, etc.) across synthetic distributions and real benchmark data (OpenEval, Inspect AI).
533
+ - `pvalues --mode pairwise` / `--mode multiarm` — Type-I error and power for pairwise and multi-arm comparisons, including multiple-comparisons correction strategies.
534
+ - `pvalues --mode ppi` — Type-I error calibration and power for every PPI-corrected test in `evalstats.tests`, swept across judge-bias severity, label fraction, and MNAR-labeling scenarios.
535
+
536
+
537
+ ## Development and Contributions
525
538
 
526
539
  For package build, release validation, and maintainer workflows, see [DEVELOPMENT.md](DEVELOPMENT.md).
527
540
 
541
+ We welcome contributions, especially refinements to our statistical methods. If you're proposing a new correction, CI method, or a fix to an existing one, we encourage battle-testing it against the [simulation harness](#reproducibility-monte-carlo-simulations) first. Please add or extend a scenario and confirm your change holds up on Type-I error and power, not just on the case that motivated it, before opening a PR. The `evalstats` repository already offers a rigorous, expansive synthetic suite that generally has held up against real data.
542
+
528
543
  ## License
529
544
 
530
545
  This repository uses two licenses:
@@ -1,6 +1,6 @@
1
1
  # evalstats
2
2
 
3
- Utilities and guidance for statistically sane analyses for comparing prompt and LLM performance. Compute statistics and visualize the results.
3
+ Rigorous statistical analysis for LLM evaluations, from model and prompt comparisons to statistical tests resilient to LLM judge bias, including in small sample data regimes.
4
4
 
5
5
  `evalstats` helps you answer questions like:
6
6
  - Is Prompt A actually better than Prompt B, or just slightly luckier on this dataset?
@@ -8,20 +8,29 @@ Utilities and guidance for statistically sane analyses for comparing prompt and
8
8
  - How sensitive is model performance to prompt wording?
9
9
  - Are my performance differences large enough to be meaningful, or just noise?
10
10
  - How stable are scores across runs, evaluators, or inputs?
11
- - What statistics test should I run in X situation?
11
+ - Can I trust my LLM-judge scores, or do they need correcting against human labels first?
12
12
 
13
- The idea is simple: you give `evalstats` your benchmark data, and it runs statistically appropriate analyses that quantify uncertainty and provide confidence bounds on your claims. Datasets can include eval scores, prompts, inputs, evaluator names, and (optionally) models. `evalstats` provides:
14
- - Plots and tests comparing prompt performance, with bootstrapped CIs and variance
15
- - Plots and tests comparing model performance across prompt variations
16
- - Constraints that guide you into performing best practices, like always considering prompt sensitivity when benchmarking model performance
13
+ You give `evalstats` your benchmark data, and it runs statistically appropriate analyses that quantify uncertainty and provide confidence bounds on your claims. It does this in two main ways:
17
14
 
18
- As well, there is a "learning" guide in `website/` which I am building out.
19
- This will include simulation- and research-backed examples of statistics for LLM evals,
20
- as well as example code (which will, obviously, tend to use `evalstats`, but
21
- the lessons hold regardless of implementation).
15
+ - **Comparisons**: Comparing models, prompts, or both at once (or any other thing you're comparing, like agent harnesses), and get 95% confidence intervals, pairwise significance tests, and multi-run sensitivity analyses. `evalstats` guides you toward best practices and choose well-calibrated methods and procedures by default, backed by simulations, and was built specifically to fill the gap of statistical knowledge for small-sample size datasets N<100; it will output stats as long as there are at least 15 samples. See [Statistics](#statistics).
16
+ - **PPI-corrected inference**: using a small set of human labels to correct bias in noisy LLM-judge scores, so your means, confidence intervals, and hypothesis tests p-values are accurately calibrated in the face of LLM judge bias. This builds on prediction-powered inference (PPI). See [PPI-Corrected Inference](#ppi-corrected-inference-means-cis-and-tests).
17
+
18
+ In particular, scientists can use our PPI-corrected statistical tests to analyze data for **mixed human-AI subject studies**, where some observations are human-labeled and the rest are graded by an LLM judge. Use `evalstats.tests` directly for LLM-judge-bias-corrected versions of:
19
+
20
+ - t-test (`ttest`, independent or paired; Welch's by default, or Student's equal-variance via `equal_var=True`)
21
+ - Mann–Whitney U (`mannwhitney`)
22
+ - Wilcoxon signed-rank (`wilcoxon`)
23
+ - One-way ANOVA (`anova_oneway`, independent or repeated-measures)
24
+ - Friedman test (`friedman`, repeated-measures rank-based)
25
+ - Kruskal-Wallis (`kruskalwallis`, independent-groups rank-based)
26
+
27
+ As long as the items for human labeling were sampled at random from the full dataset, p-values will stay calibrated even when the LLM judge is biased or miscalibrated. These corrections are validated via extensive Monte Carlo simulations (see `simulations/harness`). To the best of our knowledge, `evalstats` provides the only known implementations of PPI-corrected rank-based nonparametric tests like Wilcoxon.
28
+
29
+ As well,
22
30
 
23
31
  > [!IMPORTANT]
24
32
  > We are actively building out this project, both the website/guide and the package.
33
+ > Aside from the package itself, there is a "learning" guide in `website/` which I am building out and will return to after writing up the simulations. This will include simulation- and research-backed examples of statistics for LLM evals, as well as example code (which will, obviously, use `evalstats`, but the lessons hold regardless of implementation).
25
34
  > If there's something you'd like to see, or guidance on a specific topic, let us know
26
35
  > by raising an Issue.
27
36
 
@@ -216,6 +225,19 @@ would have gotten from a fully human-labeled study (Angelopoulos et al., 2023).
216
225
  Most PPI correction methods use PPIBoot (bootstrap variant of PPI; Zrnic, 2024).
217
226
  Implemented corrections have been battle-tested via simulations (see `simulations/sim_type_i_calibration.py`).
218
227
 
228
+ > **Important: which items get a human label must be chosen uniformly at
229
+ > random.** PPI correction assumes the labeled subset is representative of
230
+ > the full dataset. If your labeling process instead targets specific items
231
+ > — e.g. "always double-check the borderline or highest-scoring responses,"
232
+ > a common real-world review habit — that's missing-not-at-random (MNAR)
233
+ > selection on the outcome, and PPI correction can stay badly miscalibrated
234
+ > **no matter how many items you label**. This isn't ordinary small-sample
235
+ > noise that more labels fixes; it was confirmed in simulation to persist
236
+ > from 15 up through 300 labeled items out of 400. See
237
+ > `evalstats.ppi.correct`'s docstring for the full analysis. If you can't
238
+ > guarantee random labeling, treat any PPI-corrected result here with
239
+ > caution regardless of the reported CI/p-value.
240
+
219
241
  ### Example: Comparing models with corrected LLM judge evals via `compare(..., alignment=...)`
220
242
 
221
243
  ```python
@@ -441,36 +463,29 @@ pip install "evalstats[lmm]"
441
463
 
442
464
  Installation details may differ on your system.
443
465
 
444
- ## Future and TODO
445
-
446
- We aim to continue to contribute to `evalstats`. Ideas for future features:
447
- - Mixed-effects models (LMMs and potentially GLMMs) for multi-input data. Currently, `evalstats` only supports the case of one input per prompt template, rather than a grid search (cross product) of different prompt variations.
448
- - A default "report" mode that outputs a PDF summarizing findings and diving into the details
449
- - Integration with ChainForge as a front-end, to bring statistical analyses to plotted evals
450
- - Help developers quantify the "semantic variance" of the provided prompt templates, and perhaps even factor this into the calculation in an intelligent way. This is important because the current implementation doesn't know about the diversity/representativity of the input dataset and prompts.
451
- - Automatic "reliability" checking that generates minor prompt variations (e.g., lightly paraphrasing) and tests model robustness to small deviations. Implement various methods for generating minor prompt variations.
452
-
453
- Another area of concern, but separate from the current focus on running stats over benchmarking scores, is helping users improve their eval and test set validity. Benchmark validity testing could use diagnostic tools from Item Response Theory, to converge on a smaller, higher-quality item set where every item is valuable (e.g., see Fluid Benchmarking). For each item in a set, know:
454
- - Difficulty: What proportion of model/prompt variants get this right? Near-zero items either have bad reference answers, are genuinely unanswerable, or represent a capability so far out of range it's not discriminating anything useful. Near-ceiling items inflate scores without adding signal.
455
- - Discrimination: Does performance on this item correlate with performance on the rest of the eval? A good item should be passed by models that do well overall and failed by models that do poorly. Low or negative discrimination is a red flag. Negative discrimination especially suggests the item may be flawed, ambiguous, or testing something orthogonal.
456
-
457
- More practically speaking, we could:
458
- - Flag always-pass and always-fail items for removal or replacement. Replace them with items at a similar difficulty level to what the user intended but with better discriminating power.
459
- - Flag negative-discrimination items for inspection. These usually have one of a few problems: ambiguous wording where reasonable models disagree on interpretation, a flawed reference answer, or the item is actually measuring a different construct than the rest of the eval. Decide whether to fix or drop.
460
- - Cluster items by similarity, either by topic or by response pattern (items that all the same models pass/fail together). Prune to the most discriminating items in each cluster. After pruning, look for construct areas that lost too many items: the user may need to write better items for that region rather than leaving it underrepresented.
461
- - Benchmark distillation: Using an IRT-style approach similar to Fluid Benchmarking to find the most informative subset of eval items, and removing less informative ones. Could offer multiple methods for this, and simulations showing how they perform. E.g.:
462
- - ```
463
- Full benchmark: 1200 items
464
- Distilled benchmark: 35 items
465
- Token savings: 96%
466
- Rank correlation: 0.94
467
- ```
468
- - Target a difficulty distribution: a well-designed benchmark has items spread across the difficulty range, with more items in the middle (where models are actually differentiated) than at the extremes. If the user's distribution is skewed too easy or hard, help them write targeted items to fill gaps.
469
-
470
- ## Development
466
+ ## Reproducibility: Monte Carlo simulations
467
+
468
+ Claims in this README like "verified in our simulations" are backed by a runnable simulation harness in `simulations/harness/` of this package. We engineered these simulations so that you can run these yourself. For instance:
469
+
470
+ ```bash
471
+ python -m simulations.harness.cli --list-cases
472
+ python -m simulations.harness.cli --official-tests
473
+ python -m simulations.harness.cli ci_single --reps 50 --sizes 10 20
474
+ python -m simulations.harness.cli pvalues --mode ppi --tests ttest wilcoxon anova_rep
475
+ ```
476
+
477
+ `--official-tests will bring up a CLI with options to run specific tests. Each runs each case's canonical, full-scale preset and writes results plus a `manifest.json` (args, output paths, key metrics, pass/fail) to `simulations/out/official_<timestamp>/`. See [`simulations/harness/README.md`](simulations/harness/README.md) for the full case list, scenario library, and verification methodology against the original standalone scripts. Note that *each* simulation can take *very long* to run; even on a MacBook Pro with an M4 Max chip and 64GB RAM, with computation paralellized across 16 CPU cores, it often takes many hours.
478
+ - `ci_single` / `ci_paired` — coverage and width of confidence interval methods (bootstrap, smoothed bootstrap, Bayesian, Wilson, etc.) across synthetic distributions and real benchmark data (OpenEval, Inspect AI).
479
+ - `pvalues --mode pairwise` / `--mode multiarm` — Type-I error and power for pairwise and multi-arm comparisons, including multiple-comparisons correction strategies.
480
+ - `pvalues --mode ppi` — Type-I error calibration and power for every PPI-corrected test in `evalstats.tests`, swept across judge-bias severity, label fraction, and MNAR-labeling scenarios.
481
+
482
+
483
+ ## Development and Contributions
471
484
 
472
485
  For package build, release validation, and maintainer workflows, see [DEVELOPMENT.md](DEVELOPMENT.md).
473
486
 
487
+ We welcome contributions, especially refinements to our statistical methods. If you're proposing a new correction, CI method, or a fix to an existing one, we encourage battle-testing it against the [simulation harness](#reproducibility-monte-carlo-simulations) first. Please add or extend a scenario and confirm your change holds up on Type-I error and power, not just on the case that motivated it, before opening a PR. The `evalstats` repository already offers a rigorous, expansive synthetic suite that generally has held up against real data.
488
+
474
489
  ## License
475
490
 
476
491
  This repository uses two licenses:
@@ -37,7 +37,7 @@ from evalstats.alignment import validate_alignment, AlignmentResult
37
37
  from evalstats import ppi
38
38
  from evalstats import tests
39
39
 
40
- __version__ = "0.2.2"
40
+ __version__ = "0.2.4"
41
41
 
42
42
  __all__ = [
43
43
  # High-level spec API