Skip to content

feat(analyzer): Add golden-dataset evaluation harness with per-PR quality report#2172

Open
yuriihavrylko wants to merge 7 commits into
data-privacy-stack:mainfrom
yuriihavrylko:feat/analyzer-evaluation-harness
Open

feat(analyzer): Add golden-dataset evaluation harness with per-PR quality report#2172
yuriihavrylko wants to merge 7 commits into
data-privacy-stack:mainfrom
yuriihavrylko:feat/analyzer-evaluation-harness

Conversation

@yuriihavrylko

Copy link
Copy Markdown
Contributor

Change Description

Adds a span-level evaluation harness that gives every PR a per-entity precision/recall/F1 and latency report for the analyzer, so recognizer and pipeline changes are reviewed with numbers instead of intuition.

What's included

  • Curated golden dataset — 46 English samples, 93 annotated spans across 12 entity types, in categories per Create a generic dataset that include some PHI / PII - to evaluate the three first modes #1810: simple one-liners, multi-entity texts (support tickets, clinical notes, logs), long documents (discharge summary, incident report, KYC), edge cases (lowercase/inverted names, adjacent entities), and negative samples with tempting lookalikes (version numbers, quantities). Values are checksum-valid where recognizers validate (Luhn, IBAN mod-97, NHS check digit). The JSON is generated from a source-of-truth script (generate_golden_en.py) so span offsets are computed, never hand-counted; a sync test fails if the JSON drifts from the generator.
  • Span evaluator — matches predictions to gold spans by entity type and character IoU (default 0.5, --iou 1.0 = exact), aggregates per-entity TP/FP/FN into precision/recall/F1, measures throughput, and renders a markdown report including every mismatch with its text for human review.
  • Baselines with enforcement built in but switched off — the checked-in baseline (baselines/spacy_en.json) turns the report into per-entity F1 deltas. --fail-on-regression exits non-zero when overall or per-entity F1 drops more than --f1-tolerance (default 0.02). CI runs report-only: flipping enforcement on is a one-line change, deliberately left as a maintainer decision once the numbers have proven stable across real PRs (e.g. a new en_core_web_lg release can shift NER results with no code change).
  • CI job — evaluates the default configuration (spaCy + pattern recognizers) and publishes the report to the workflow step summary (~1–2 min, no extras needed). Other configurations (transformers, GLiNER) are runnable via --analyzer-conf <yaml> with their own baselines; wiring them into a nightly matrix is a follow-up.

Why this shape

  • Report-only first: a report is easy to trust and merge; a gate that can fail other contributors' builds deserves its own switch-on decision after the numbers have been observed. The mechanism ships now so that decision is a one-liner, not another PR.
  • Whole-pipeline evaluation: running AnalyzerEngine.analyze() end-to-end catches what unit tests structurally can't — a new recognizer's regex firing on other entities' values, a registry refactor silently dropping a recognizer (entity recall → 0), NLP model/label-mapping shifts, threshold plumbing changes.
  • Internal evaluator (~300 lines) instead of a presidio-evaluator dependency: keeps CI installs minimal and avoids coupling to an external repo; synthetic generated data (per Evaluate precision/recall/latency during CI #1639's template+Faker design) plugs into the same dataset format later.

The report already surfaces known issues — current baseline: precision 0.724, recall 0.989, F1 0.836. URL false positives inside email addresses (#1498, #1316) show as URL precision 0.292; PHONE_NUMBER fires on SSNs and IPs; spaCy tags bare numbers as DATE_TIME.

Roadmap (details in tests/evaluation/README.md): this PR → switch on --fail-on-regression in CI → synthetic template+Faker data generation, with templates required for new recognizers (#1639) → nightly multi-config matrix (transformers/GLiNER/LLM) and non-English datasets, feeding the fast/balanced/accurate recipes comparison (#1809).

Issue reference

Fixes #1810
Advances #1639 (phase 1 of the evaluation roadmap); groundwork for #1809

Checklist

  • I have reviewed the contribution guidelines
  • I agree to follow this project's Code of Conduct
  • I confirm that I have the right to submit this contribution and that it does not knowingly contain proprietary or confidential code.
  • My code includes unit tests
  • All unit tests and lint checks pass locally
  • My PR contains documentation updates / additions if required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create a generic dataset that include some PHI / PII - to evaluate the three first modes

1 participant