evalsuite-python 0.3.1__tar.gz → 0.4.1__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.
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/CHANGELOG.md +57 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/PKG-INFO +65 -22
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/README.md +52 -21
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/pyproject.toml +17 -1
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/__init__.py +5 -1
- evalsuite_python-0.4.1/src/evalsuite/_bench_metrics.py +1391 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/benchmarks.py +171 -10
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/cli/main.py +33 -2
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/clinical/metrics.py +7 -4
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/plot.py +146 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/_resolve.py +23 -3
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/compare.py +7 -3
- evalsuite_python-0.4.1/src/evalsuite/text/__init__.py +152 -0
- evalsuite_python-0.4.1/src/evalsuite/text/_common.py +94 -0
- evalsuite_python-0.4.1/src/evalsuite/text/factuality.py +469 -0
- evalsuite_python-0.4.1/src/evalsuite/text/generation.py +1127 -0
- evalsuite_python-0.4.1/src/evalsuite/text/judge.py +532 -0
- evalsuite_python-0.4.1/src/evalsuite/text/qa.py +108 -0
- evalsuite_python-0.4.1/src/evalsuite/text/rag.py +235 -0
- evalsuite_python-0.4.1/src/evalsuite/text/reasoning.py +215 -0
- evalsuite_python-0.4.1/src/evalsuite/text/report.py +158 -0
- evalsuite_python-0.4.1/src/evalsuite/text/retrieval.py +238 -0
- evalsuite_python-0.4.1/src/evalsuite/text/semantic.py +465 -0
- evalsuite_python-0.4.1/src/evalsuite/text/structured.py +789 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/version.py +1 -1
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/integration/test_readme_examples.py +25 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/output/test_benchmarks.py +48 -2
- evalsuite_python-0.4.1/tests/text/test_against_references.py +256 -0
- evalsuite_python-0.4.1/tests/text/test_text_edges.py +175 -0
- evalsuite_python-0.4.1/tests/text/test_v040.py +835 -0
- evalsuite_python-0.4.1/tests/vision/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/.gitignore +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/CONTRIBUTING.md +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/LICENSE +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/__main__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/api.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/calibration.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/classification/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/classification/_common.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/classification/metrics.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/cli/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/clinical/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/clinical/report.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/context.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/exceptions.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/export.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/registry.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/result.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/types.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/core/validation.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/py.typed +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/regression/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/regression/metrics.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/reporting.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/effect.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/hypothesis.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/intervals.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/paired.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/stats/results.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/vision/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/vision/detection.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/src/evalsuite/vision/segmentation.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/classification/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/classification/test_against_sklearn.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/clinical/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/clinical/test_outputs.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/clinical/test_v020.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/conftest.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/integration/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/integration/test_qa.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/integration/test_repo_hygiene.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/output/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/output/test_cli.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/output/test_plot.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/output/test_reporting.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/regression/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/regression/test_against_sklearn.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/stats/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/stats/test_branches.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/stats/test_compare.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/stats/test_reference.py +0 -0
- {evalsuite_python-0.3.1/tests/unit → evalsuite_python-0.4.1/tests/text}/__init__.py +0 -0
- {evalsuite_python-0.3.1/tests/vision → evalsuite_python-0.4.1/tests/unit}/__init__.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/unit/test_core.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/unit/test_edges.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/vision/test_detection.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/vision/test_edges.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/vision/test_outputs.py +0 -0
- {evalsuite_python-0.3.1 → evalsuite_python-0.4.1}/tests/vision/test_segmentation.py +0 -0
|
@@ -6,6 +6,63 @@ All notable changes to this project are documented here. The format follows
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.4.1] - 2026-10-09
|
|
10
|
+
|
|
11
|
+
Benchmarks for every metric. No API changed.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `run_benchmarks(suite="metrics")` and `evalsuite benchmark --suite metrics`: one row for each of the 147
|
|
15
|
+
registered metrics and statistics functions, compared with a reference library (scikit-learn, SciPy,
|
|
16
|
+
statsmodels, pycocotools, sacreBLEU, rouge-score, NLTK, pycocoevalcap, ranx, krippendorff, choix, POT,
|
|
17
|
+
jsonschema) where one exists, otherwise with an independent NumPy / standard-library implementation of
|
|
18
|
+
the textbook formula; learned, judge-dependent and randomised procedures are timed alone. All 128
|
|
19
|
+
comparisons agree to 1e-9. A test keeps the suite in step with the registry.
|
|
20
|
+
- `scripts/bench_metrics_report.py` renders the per-metric table for BENCHMARKS.md and the website.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- `net_benefit` at a single threshold computes in one pass instead of sorting (about 3× faster).
|
|
24
|
+
- `perplexity` and `cross_entropy` validate the pooled tokens once instead of each sequence separately
|
|
25
|
+
(5–9× faster for many short sequences); errors still name the offending sequence.
|
|
26
|
+
|
|
27
|
+
## [0.4.0] - 2026-10-09
|
|
28
|
+
|
|
29
|
+
LLM evaluation (the v0.4.0 roadmap). No existing API changed.
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
- `es.text` and top-level functions for language-model evaluation; 69 new registered metrics, each checked
|
|
33
|
+
against a reference implementation where one exists:
|
|
34
|
+
- Text generation: BLEU, sentence BLEU, chrF/chrF++, TER (sacreBLEU), ROUGE-1/2/L/Lsum (rouge-score),
|
|
35
|
+
METEOR (NLTK, synonyms pluggable), CIDEr-D (pycocoevalcap), perplexity, cross-entropy, Distinct-n,
|
|
36
|
+
Self-BLEU, MAUVE (mauve-text divergence frontier, NumPy k-means).
|
|
37
|
+
- Semantic: BERTScore, embedding cosine / Euclidean / Manhattan, MoverScore (exact transport, = POT), and
|
|
38
|
+
`model_score` to run COMET, BLEURT, BARTScore, AlignScore or any scorer with intervals and comparison.
|
|
39
|
+
- Factuality: faithfulness, hallucination (unsupported-claim) rate, groundedness, citation precision and
|
|
40
|
+
recall (ALCE), claim-verification accuracy, knowledge consistency, answer correctness and relevance
|
|
41
|
+
(RAGAS), abstention accuracy, exact match and token F1 (SQuAD).
|
|
42
|
+
- LLM-as-a-judge: win rate, Bradley–Terry (= choix), Elo, Krippendorff's alpha (= krippendorff), Fleiss'
|
|
43
|
+
kappa (= statsmodels), judge–human agreement, position consistency, verbosity and self-preference bias,
|
|
44
|
+
rubric scores.
|
|
45
|
+
- Reasoning: pass@k, majority-vote accuracy, answer extraction and benchmark accuracy (GSM8K, MATH,
|
|
46
|
+
multiple choice).
|
|
47
|
+
- RAG: Precision/Recall/Hit rate@k, MRR, MAP, NDCG (= ranx), context precision, recall and relevance,
|
|
48
|
+
latency summary, task success rate, failure attribution.
|
|
49
|
+
- Structured output: JSON validity, JSON Schema compliance (built-in validator, agrees with jsonschema),
|
|
50
|
+
XML validity, required-field accuracy, tool selection / argument accuracy and tool-call F1, API-call
|
|
51
|
+
success, instruction compliance, constraint satisfaction, format compliance, multi-turn retention,
|
|
52
|
+
extra-content rate.
|
|
53
|
+
- `es.text_report` and `evalsuite text` (CLI) for the reference-based text metrics in one report.
|
|
54
|
+
- `bootstrap_ci`, `compare` and the paired tests resample whole items (texts, reference lists, rankings) for
|
|
55
|
+
these metrics, so corpus metrics such as BLEU get proper intervals.
|
|
56
|
+
- Benchmark suite `llm` against sacreBLEU, rouge-score, NLTK, ranx, krippendorff and jsonschema.
|
|
57
|
+
- `llm` extra (`nltk`) for METEOR's default Porter stemmer.
|
|
58
|
+
- Plots: `es.plot.ratings` (Bradley–Terry or Elo leaderboard with bootstrap intervals), `es.plot.win_matrix`
|
|
59
|
+
(pairwise win rates) and `es.plot.text_scores` (per-example score distributions by system).
|
|
60
|
+
- Benchmark overall summary counts cases without their size suffixes.
|
|
61
|
+
|
|
62
|
+
### Not included
|
|
63
|
+
- SPICE (needs a Java scene-graph parser); BLEURT, COMET, BARTScore and AlignScore run through
|
|
64
|
+
`es.model_score` with your model rather than being bundled.
|
|
65
|
+
|
|
9
66
|
## [0.3.1] - 2026-10-09
|
|
10
67
|
|
|
11
68
|
Quality-assurance release: release pipeline, packaging checks, edge-case fixes and an overall benchmark.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: evalsuite-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.1
|
|
4
4
|
Summary: A unified Python framework for machine-learning, clinical, statistical, segmentation, object-detection, uncertainty, and model evaluation.
|
|
5
5
|
Project-URL: Homepage, https://evalsuite-nine.vercel.app
|
|
6
6
|
Project-URL: Documentation, https://evalsuite-nine.vercel.app/docs
|
|
@@ -36,22 +36,34 @@ Requires-Dist: pandas>=1.4
|
|
|
36
36
|
Requires-Dist: scipy>=1.8
|
|
37
37
|
Provides-Extra: all
|
|
38
38
|
Requires-Dist: matplotlib>=3.5; extra == 'all'
|
|
39
|
+
Requires-Dist: nltk>=3.8; extra == 'all'
|
|
39
40
|
Requires-Dist: pillow>=9; extra == 'all'
|
|
40
41
|
Provides-Extra: dev
|
|
41
42
|
Requires-Dist: build; extra == 'dev'
|
|
43
|
+
Requires-Dist: choix>=0.3; extra == 'dev'
|
|
42
44
|
Requires-Dist: hypothesis>=6.80; extra == 'dev'
|
|
45
|
+
Requires-Dist: jsonschema>=4.18; extra == 'dev'
|
|
46
|
+
Requires-Dist: krippendorff>=0.6; extra == 'dev'
|
|
43
47
|
Requires-Dist: matplotlib>=3.5; extra == 'dev'
|
|
44
48
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
49
|
+
Requires-Dist: nltk>=3.8; extra == 'dev'
|
|
45
50
|
Requires-Dist: pandas-stubs; extra == 'dev'
|
|
46
51
|
Requires-Dist: pillow>=9; extra == 'dev'
|
|
47
52
|
Requires-Dist: pip-audit; extra == 'dev'
|
|
53
|
+
Requires-Dist: pot>=0.9; (python_version < '3.14') and extra == 'dev'
|
|
54
|
+
Requires-Dist: pycocoevalcap>=1.2; extra == 'dev'
|
|
48
55
|
Requires-Dist: pycocotools>=2.0.7; extra == 'dev'
|
|
49
56
|
Requires-Dist: pytest-cov>=4; extra == 'dev'
|
|
50
57
|
Requires-Dist: pytest>=7; extra == 'dev'
|
|
58
|
+
Requires-Dist: ranx>=0.3.19; (python_version < '3.14') and extra == 'dev'
|
|
59
|
+
Requires-Dist: rouge-score>=0.1.2; extra == 'dev'
|
|
51
60
|
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
61
|
+
Requires-Dist: sacrebleu>=2.4; extra == 'dev'
|
|
52
62
|
Requires-Dist: scikit-learn>=1.4; extra == 'dev'
|
|
53
63
|
Requires-Dist: statsmodels>=0.13; extra == 'dev'
|
|
54
64
|
Requires-Dist: twine; extra == 'dev'
|
|
65
|
+
Provides-Extra: llm
|
|
66
|
+
Requires-Dist: nltk>=3.8; extra == 'llm'
|
|
55
67
|
Provides-Extra: plot
|
|
56
68
|
Requires-Dist: matplotlib>=3.5; extra == 'plot'
|
|
57
69
|
Provides-Extra: vision
|
|
@@ -65,12 +77,14 @@ Description-Content-Type: text/markdown
|
|
|
65
77
|
[](https://pypi.org/project/evalsuite-python/)
|
|
66
78
|
[](LICENSE)
|
|
67
79
|
|
|
68
|
-
**Unified, reproducible evaluation for machine learning and research.**
|
|
80
|
+
**Unified, reproducible evaluation for machine learning, LLM and research.**
|
|
69
81
|
|
|
70
82
|
EvalSuite brings classification, regression, clinical, statistical, segmentation and object-detection
|
|
71
83
|
evaluation into one consistent, validated, documented framework.
|
|
72
84
|
|
|
73
|
-
> **Status: stable (0.
|
|
85
|
+
> **Status: stable (0.4.1).** Every item on the 0.1.0, 0.2.0, 0.3.0 and 0.4.0 roadmaps is implemented and verified
|
|
86
|
+
> (except SPICE, which needs a Java scene-graph parser).
|
|
87
|
+
> **LLM evaluation is available from 0.4.0**; LLM systems, safety and operations are planned for 0.5.0.
|
|
74
88
|
|
|
75
89
|
## Installation
|
|
76
90
|
|
|
@@ -226,6 +240,22 @@ Models can be compared over the same images with intervals and paired tests, as
|
|
|
226
240
|
`es.compare(y_true, {"unet": masks_a, "deeplab": masks_b})` resamples images; for detection it compares
|
|
227
241
|
mAP.
|
|
228
242
|
|
|
243
|
+
## LLM evaluation
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
es.bleu(references, predictions) # sacreBLEU-identical; also chrf, ter, rouge_l, meteor, cider
|
|
247
|
+
es.text_report(references, predictions) # BLEU, chrF(++), TER, ROUGE, METEOR, EM, token F1 at once
|
|
248
|
+
es.bertscore(ref_token_embs, pred_token_embs) # from your encoder's embeddings; also mauve, moverscore
|
|
249
|
+
es.model_score(refs, preds, scorer=comet_fn) # any learned metric or judge, with intervals and compare
|
|
250
|
+
es.faithfulness(claim_verdicts) # also hallucination_rate, citation_recall, answer_correctness
|
|
251
|
+
es.bradley_terry(comparisons, scale="elo") # also win_rate, elo_ratings, krippendorff_alpha
|
|
252
|
+
es.ndcg_at_k(relevant, retrieved, k=10) # also mrr, context_precision, context_recall
|
|
253
|
+
es.json_schema_compliance(outputs, schema) # also tool_call_f1, instruction_compliance_rate
|
|
254
|
+
es.pass_at_k(n_samples, n_correct, k=10) # also benchmark_accuracy(..., style="gsm8k")
|
|
255
|
+
es.compare(references, {"a": preds_a, "b": preds_b}, metrics=["bleu", "rouge_l"]) # paired over examples
|
|
256
|
+
es.plot.ratings(comparisons) # Bradley–Terry leaderboard with intervals; also win_matrix, text_scores
|
|
257
|
+
```
|
|
258
|
+
|
|
229
259
|
## Classification report
|
|
230
260
|
|
|
231
261
|
```python
|
|
@@ -283,28 +313,41 @@ Input files can be CSV, TSV, Parquet or JSON. Output format follows `--format` o
|
|
|
283
313
|
## Performance
|
|
284
314
|
|
|
285
315
|
Benchmarked against reference implementations on the same data (fastest of 5 runs; Python 3.12, NumPy 2.5,
|
|
286
|
-
Linux x86_64). **Overall:
|
|
287
|
-
difference
|
|
288
|
-
|
|
289
|
-
segmentation; 1,000 images for detection and 50 for Hausdorff), in
|
|
316
|
+
Linux x86_64). **Overall: 63 of 63 rows agree with the reference** (largest
|
|
317
|
+
difference 1.8e-14), 42 are faster, and the geometric-mean speed-up across all
|
|
318
|
+
21 cases and three sizes is **2.12×**. At 1,000,000 samples (pixels for
|
|
319
|
+
segmentation; 1,000 images for detection and 50 for Hausdorff; 10,000 examples for the LLM cases), in
|
|
320
|
+
alphabetical order:
|
|
290
321
|
|
|
291
322
|
| Case | Reference | EvalSuite (ms) | Reference (ms) | Speed-up |
|
|
292
323
|
| --- | --- | ---: | ---: | ---: |
|
|
293
|
-
| 10 classes: macro F1 | scikit-learn |
|
|
294
|
-
|
|
|
295
|
-
| binary:
|
|
296
|
-
|
|
|
297
|
-
|
|
|
298
|
-
| clinical:
|
|
299
|
-
|
|
|
300
|
-
|
|
|
301
|
-
|
|
|
302
|
-
|
|
|
303
|
-
|
|
|
304
|
-
|
|
|
305
|
-
|
|
|
306
|
-
|
|
|
307
|
-
| statistics:
|
|
324
|
+
| 10 classes: macro F1 | scikit-learn | 23.8 | 135.5 | **5.7×** |
|
|
325
|
+
| agreement: Krippendorff's alpha, interval (4 raters × 10000 items) | krippendorff | 3.5 | 3.4 | 0.96× |
|
|
326
|
+
| binary: 8 label metrics via evaluate() | scikit-learn | 28.5 | 1023.8 | **36.0×** |
|
|
327
|
+
| binary: ROC AUC | scikit-learn | 187.4 | 327.3 | **1.7×** |
|
|
328
|
+
| calibration: slope and intercept | statsmodels | 205.7 | 1173.7 | **5.7×** |
|
|
329
|
+
| clinical: diagnostic report (7 CIs) | statsmodels | 19.6 | 4.9 | 0.25× |
|
|
330
|
+
| clinical: sensitivity, specificity, LR+, LR− | scikit-learn | 75.2 | 411.5 | **5.5×** |
|
|
331
|
+
| decision curve: 99 thresholds | NumPy loop | 165.0 | 201.9 | **1.2×** |
|
|
332
|
+
| detection: COCO evaluation (1000 images) | pycocotools | 838.7 | 848.6 | **1.0×** |
|
|
333
|
+
| multiple testing: Hochberg (n p-values) | statsmodels | 72.1 | 79.0 | **1.1×** |
|
|
334
|
+
| regression: MAE, MSE, RMSE, R² via evaluate() | scikit-learn | 22.9 | 10.6 | 0.47× |
|
|
335
|
+
| retrieval: MRR, MAP@20, NDCG@10 (10000 queries) | ranx | 170.4 | 861.0 | **5.1×** |
|
|
336
|
+
| segmentation: Dice and IoU per class (n = pixels) | scikit-learn | 34.3 | 256.0 | **7.5×** |
|
|
337
|
+
| segmentation: Hausdorff distance (50 images) | SciPy | 24.2 | 19.8 | 0.82× |
|
|
338
|
+
| statistics: Cramér's V (5×5 table) | SciPy | 0.2 | 0.2 | **1.0×** |
|
|
339
|
+
| statistics: Mann–Whitney U | SciPy | 353.5 | 340.6 | 0.96× |
|
|
340
|
+
| statistics: Welch t-test | SciPy | 16.1 | 8.3 | 0.52× |
|
|
341
|
+
| structured: JSON Schema compliance (10000 documents) | jsonschema | 144.6 | 330.5 | **2.3×** |
|
|
342
|
+
| text: corpus BLEU and chrF (10000 sentences) | sacreBLEU | 2789.8 | 3051.8 | **1.1×** |
|
|
343
|
+
| text: METEOR, exact and stem matches (10000 sentences) | NLTK | 488.1 | 626.7 | **1.3×** |
|
|
344
|
+
| text: ROUGE-1, ROUGE-2, ROUGE-L (10000 sentences) | rouge-score | 1290.1 | 1095.6 | 0.85× |
|
|
345
|
+
|
|
346
|
+
**Every metric is benchmarked too** (`evalsuite benchmark --suite metrics`): all 147 registered metrics and
|
|
347
|
+
statistics functions at 10,000 and 100,000 samples. 79 are compared with a reference library, 49 with an
|
|
348
|
+
independent textbook formula and 19 (learned, judge-dependent or randomised) are timed alone; **all 128
|
|
349
|
+
comparisons agree**, and against the libraries the geometric-mean speed-up is **2.76×** (123 of 158
|
|
350
|
+
measurements faster). Per-metric table in BENCHMARKS.md.
|
|
308
351
|
|
|
309
352
|
`evaluate()` validates inputs once and builds the confusion matrix once for all metrics, which is where most
|
|
310
353
|
of the speed-up comes from. Hypothesis tests use SciPy underneath, so they match its speed at best; rows
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
[](https://pypi.org/project/evalsuite-python/)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
|
|
8
|
-
**Unified, reproducible evaluation for machine learning and research.**
|
|
8
|
+
**Unified, reproducible evaluation for machine learning, LLM and research.**
|
|
9
9
|
|
|
10
10
|
EvalSuite brings classification, regression, clinical, statistical, segmentation and object-detection
|
|
11
11
|
evaluation into one consistent, validated, documented framework.
|
|
12
12
|
|
|
13
|
-
> **Status: stable (0.
|
|
13
|
+
> **Status: stable (0.4.1).** Every item on the 0.1.0, 0.2.0, 0.3.0 and 0.4.0 roadmaps is implemented and verified
|
|
14
|
+
> (except SPICE, which needs a Java scene-graph parser).
|
|
15
|
+
> **LLM evaluation is available from 0.4.0**; LLM systems, safety and operations are planned for 0.5.0.
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
@@ -166,6 +168,22 @@ Models can be compared over the same images with intervals and paired tests, as
|
|
|
166
168
|
`es.compare(y_true, {"unet": masks_a, "deeplab": masks_b})` resamples images; for detection it compares
|
|
167
169
|
mAP.
|
|
168
170
|
|
|
171
|
+
## LLM evaluation
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
es.bleu(references, predictions) # sacreBLEU-identical; also chrf, ter, rouge_l, meteor, cider
|
|
175
|
+
es.text_report(references, predictions) # BLEU, chrF(++), TER, ROUGE, METEOR, EM, token F1 at once
|
|
176
|
+
es.bertscore(ref_token_embs, pred_token_embs) # from your encoder's embeddings; also mauve, moverscore
|
|
177
|
+
es.model_score(refs, preds, scorer=comet_fn) # any learned metric or judge, with intervals and compare
|
|
178
|
+
es.faithfulness(claim_verdicts) # also hallucination_rate, citation_recall, answer_correctness
|
|
179
|
+
es.bradley_terry(comparisons, scale="elo") # also win_rate, elo_ratings, krippendorff_alpha
|
|
180
|
+
es.ndcg_at_k(relevant, retrieved, k=10) # also mrr, context_precision, context_recall
|
|
181
|
+
es.json_schema_compliance(outputs, schema) # also tool_call_f1, instruction_compliance_rate
|
|
182
|
+
es.pass_at_k(n_samples, n_correct, k=10) # also benchmark_accuracy(..., style="gsm8k")
|
|
183
|
+
es.compare(references, {"a": preds_a, "b": preds_b}, metrics=["bleu", "rouge_l"]) # paired over examples
|
|
184
|
+
es.plot.ratings(comparisons) # Bradley–Terry leaderboard with intervals; also win_matrix, text_scores
|
|
185
|
+
```
|
|
186
|
+
|
|
169
187
|
## Classification report
|
|
170
188
|
|
|
171
189
|
```python
|
|
@@ -223,28 +241,41 @@ Input files can be CSV, TSV, Parquet or JSON. Output format follows `--format` o
|
|
|
223
241
|
## Performance
|
|
224
242
|
|
|
225
243
|
Benchmarked against reference implementations on the same data (fastest of 5 runs; Python 3.12, NumPy 2.5,
|
|
226
|
-
Linux x86_64). **Overall:
|
|
227
|
-
difference
|
|
228
|
-
|
|
229
|
-
segmentation; 1,000 images for detection and 50 for Hausdorff), in
|
|
244
|
+
Linux x86_64). **Overall: 63 of 63 rows agree with the reference** (largest
|
|
245
|
+
difference 1.8e-14), 42 are faster, and the geometric-mean speed-up across all
|
|
246
|
+
21 cases and three sizes is **2.12×**. At 1,000,000 samples (pixels for
|
|
247
|
+
segmentation; 1,000 images for detection and 50 for Hausdorff; 10,000 examples for the LLM cases), in
|
|
248
|
+
alphabetical order:
|
|
230
249
|
|
|
231
250
|
| Case | Reference | EvalSuite (ms) | Reference (ms) | Speed-up |
|
|
232
251
|
| --- | --- | ---: | ---: | ---: |
|
|
233
|
-
| 10 classes: macro F1 | scikit-learn |
|
|
234
|
-
|
|
|
235
|
-
| binary:
|
|
236
|
-
|
|
|
237
|
-
|
|
|
238
|
-
| clinical:
|
|
239
|
-
|
|
|
240
|
-
|
|
|
241
|
-
|
|
|
242
|
-
|
|
|
243
|
-
|
|
|
244
|
-
|
|
|
245
|
-
|
|
|
246
|
-
|
|
|
247
|
-
| statistics:
|
|
252
|
+
| 10 classes: macro F1 | scikit-learn | 23.8 | 135.5 | **5.7×** |
|
|
253
|
+
| agreement: Krippendorff's alpha, interval (4 raters × 10000 items) | krippendorff | 3.5 | 3.4 | 0.96× |
|
|
254
|
+
| binary: 8 label metrics via evaluate() | scikit-learn | 28.5 | 1023.8 | **36.0×** |
|
|
255
|
+
| binary: ROC AUC | scikit-learn | 187.4 | 327.3 | **1.7×** |
|
|
256
|
+
| calibration: slope and intercept | statsmodels | 205.7 | 1173.7 | **5.7×** |
|
|
257
|
+
| clinical: diagnostic report (7 CIs) | statsmodels | 19.6 | 4.9 | 0.25× |
|
|
258
|
+
| clinical: sensitivity, specificity, LR+, LR− | scikit-learn | 75.2 | 411.5 | **5.5×** |
|
|
259
|
+
| decision curve: 99 thresholds | NumPy loop | 165.0 | 201.9 | **1.2×** |
|
|
260
|
+
| detection: COCO evaluation (1000 images) | pycocotools | 838.7 | 848.6 | **1.0×** |
|
|
261
|
+
| multiple testing: Hochberg (n p-values) | statsmodels | 72.1 | 79.0 | **1.1×** |
|
|
262
|
+
| regression: MAE, MSE, RMSE, R² via evaluate() | scikit-learn | 22.9 | 10.6 | 0.47× |
|
|
263
|
+
| retrieval: MRR, MAP@20, NDCG@10 (10000 queries) | ranx | 170.4 | 861.0 | **5.1×** |
|
|
264
|
+
| segmentation: Dice and IoU per class (n = pixels) | scikit-learn | 34.3 | 256.0 | **7.5×** |
|
|
265
|
+
| segmentation: Hausdorff distance (50 images) | SciPy | 24.2 | 19.8 | 0.82× |
|
|
266
|
+
| statistics: Cramér's V (5×5 table) | SciPy | 0.2 | 0.2 | **1.0×** |
|
|
267
|
+
| statistics: Mann–Whitney U | SciPy | 353.5 | 340.6 | 0.96× |
|
|
268
|
+
| statistics: Welch t-test | SciPy | 16.1 | 8.3 | 0.52× |
|
|
269
|
+
| structured: JSON Schema compliance (10000 documents) | jsonschema | 144.6 | 330.5 | **2.3×** |
|
|
270
|
+
| text: corpus BLEU and chrF (10000 sentences) | sacreBLEU | 2789.8 | 3051.8 | **1.1×** |
|
|
271
|
+
| text: METEOR, exact and stem matches (10000 sentences) | NLTK | 488.1 | 626.7 | **1.3×** |
|
|
272
|
+
| text: ROUGE-1, ROUGE-2, ROUGE-L (10000 sentences) | rouge-score | 1290.1 | 1095.6 | 0.85× |
|
|
273
|
+
|
|
274
|
+
**Every metric is benchmarked too** (`evalsuite benchmark --suite metrics`): all 147 registered metrics and
|
|
275
|
+
statistics functions at 10,000 and 100,000 samples. 79 are compared with a reference library, 49 with an
|
|
276
|
+
independent textbook formula and 19 (learned, judge-dependent or randomised) are timed alone; **all 128
|
|
277
|
+
comparisons agree**, and against the libraries the geometric-mean speed-up is **2.76×** (123 of 158
|
|
278
|
+
measurements faster). Per-metric table in BENCHMARKS.md.
|
|
248
279
|
|
|
249
280
|
`evaluate()` validates inputs once and builds the confusion matrix once for all metrics, which is where most
|
|
250
281
|
of the speed-up comes from. Hypothesis tests use SciPy underneath, so they match its speed at best; rows
|
|
@@ -38,7 +38,8 @@ dependencies = ["numpy>=1.22", "scipy>=1.8", "pandas>=1.4"]
|
|
|
38
38
|
[project.optional-dependencies]
|
|
39
39
|
plot = ["matplotlib>=3.5"]
|
|
40
40
|
vision = ["pillow>=9"]
|
|
41
|
-
|
|
41
|
+
llm = ["nltk>=3.8"]
|
|
42
|
+
all = ["matplotlib>=3.5", "pillow>=9", "nltk>=3.8"]
|
|
42
43
|
dev = [
|
|
43
44
|
"pytest>=7",
|
|
44
45
|
"pytest-cov>=4",
|
|
@@ -48,6 +49,15 @@ dev = [
|
|
|
48
49
|
"matplotlib>=3.5",
|
|
49
50
|
"pillow>=9",
|
|
50
51
|
"pycocotools>=2.0.7",
|
|
52
|
+
"nltk>=3.8",
|
|
53
|
+
"sacrebleu>=2.4",
|
|
54
|
+
"rouge-score>=0.1.2",
|
|
55
|
+
"pycocoevalcap>=1.2",
|
|
56
|
+
"jsonschema>=4.18",
|
|
57
|
+
"choix>=0.3",
|
|
58
|
+
"krippendorff>=0.6",
|
|
59
|
+
"pot>=0.9; python_version < '3.14'",
|
|
60
|
+
"ranx>=0.3.19; python_version < '3.14'",
|
|
51
61
|
"ruff>=0.6",
|
|
52
62
|
"mypy>=1.10",
|
|
53
63
|
"pandas-stubs",
|
|
@@ -99,6 +109,12 @@ files = ["src/evalsuite"]
|
|
|
99
109
|
module = ["scipy.*", "matplotlib.*"]
|
|
100
110
|
ignore_missing_imports = true
|
|
101
111
|
|
|
112
|
+
[[tool.mypy.overrides]]
|
|
113
|
+
# optional reference libraries used only by the benchmarks and METEOR's default stemmer
|
|
114
|
+
module = ["sacrebleu.*", "rouge_score.*", "nltk.*", "ranx.*", "krippendorff.*", "jsonschema.*", "pycocotools.*"]
|
|
115
|
+
ignore_missing_imports = true
|
|
116
|
+
follow_untyped_imports = false
|
|
117
|
+
|
|
102
118
|
[tool.pytest.ini_options]
|
|
103
119
|
testpaths = ["tests"]
|
|
104
120
|
addopts = "-q --strict-markers"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
>>> print(result.summary()) # doctest: +SKIP
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from . import calibration, classification, clinical, plot, regression, stats, vision
|
|
8
|
+
from . import calibration, classification, clinical, plot, regression, stats, text, vision
|
|
9
9
|
from .api import evaluate
|
|
10
10
|
from .calibration import (
|
|
11
11
|
CalibrationReport,
|
|
@@ -110,6 +110,8 @@ from .stats import (
|
|
|
110
110
|
t_test,
|
|
111
111
|
wilcoxon_test,
|
|
112
112
|
)
|
|
113
|
+
from .text import * # noqa: F403 (every LLM-evaluation function, listed in text.__all__)
|
|
114
|
+
from .text import __all__ as _text_all
|
|
113
115
|
from .version import __version__
|
|
114
116
|
from .vision import (
|
|
115
117
|
DetectionReport,
|
|
@@ -134,6 +136,7 @@ from .vision import (
|
|
|
134
136
|
)
|
|
135
137
|
|
|
136
138
|
__all__ = [
|
|
139
|
+
"text",
|
|
137
140
|
"SegmentationReport",
|
|
138
141
|
"segmentation_report",
|
|
139
142
|
"detection_pr_curve",
|
|
@@ -258,3 +261,4 @@ __all__ = [
|
|
|
258
261
|
"specificity",
|
|
259
262
|
"top_k_accuracy",
|
|
260
263
|
]
|
|
264
|
+
__all__ += list(_text_all)
|