Skip to content

UK AI Evaluation harness

Independent, reproducible evaluation of diagnostic and predictive machine-learning classifiers, working from model outputs and ground-truth labels only. No model weights, no images, no patient-identifiable data need to leave the developer's or the hospital's environment. The harness is standard-library Python: clone it and run it, there is nothing to install.

ci

Built and maintained by UK AI Evaluation Ltd, an independent AI assurance company in London. The method the harness implements is published and version-tagged: METH-0.2, Diagnostic / Predictive-ML Evaluation Track (a copy is in docs/).

Status. Pre-product research tooling, released so that the method and the code can be read, run and challenged by anyone. Nothing produced by this harness is a certified or accredited assessment, and UK AI Evaluation is not affiliated with, certified by, or endorsed by the MHRA, the UK AI Security Institute or the NHS.

Run it in thirty seconds

git clone https://github.com/ukaievaluation/harness.git
cd harness
python3 -m ukaie.harness.run_demo

That runs the seeded synthetic corpus, which plants known failures (a transferability drop, miscalibration, a shortcut, a subgroup gap, a sensitivity shortfall and post-deployment drift), scores it through the engine, and exits non-zero if any planted failure is missed. The synthetic run validates the detector; it is never evidence about a real model.

To evaluate a real model, export a CSV of its predictions and run:

python3 -m ukaie.harness.run_demo \
    --internal-csv developer_site.csv \
    --external-csv deployment_site.csv \
    --monitoring-csv monitoring.csv --monitoring-period-col period \
    --vendor-auroc 0.82 --sensitivity-floor 0.85 \
    --cluster-col patient_id \
    --no-selftest --out scorecard.json

examples/ contains a generator for three example CSVs in exactly this shape, so the command above can be tried before any real data is touched.

The input contract

One row per case. This is the whole surface; the harness never calls the model.

Column Required Meaning
label yes ground truth, 0 or 1
score yes the model's output probability for the positive class, 0 to 1
id no a row identifier; generated if absent, and need never be a patient identifier
group no the stratum for subgroup analysis (D4); may be supplied pre-coded as opaque labels
site no acquisition source (hospital, scanner, assay)
score_perturbed no the model's score on the same case with the suspected shortcut removed (enables D3)
period no monitoring period, for a single post-deployment export split with --monitoring-period-col

Loader: ukaie/harness/adapters.py.

What it measures

The method defines seven dimensions. Which rows are computed by this version is stated on the face of the method (METH-0.2 §3) and repeated here.

Dimension What it asks This version
D1 Discrimination and transferability Does performance hold when the data crosses the axis the model meets in deployment? AUROC with tie handling, delta-AUROC developer to deployment site
D2 Calibration Do the probabilities mean what they say, on both sites? ECE, Brier, calibration slope and intercept
D3 Shortcut learning and leakage Is it keying off a scanner, site or marker rather than pathology? perturbation-degradation probe and conditional site-gap probe (severity band gated, see below)
D4 Subgroup and equity Does it work equally across groups, and can we tell? per-group AUROC, sensitivity and false-negative rate with an underpowered-group guard
D5 Operating point At the deployed threshold, does it clear the sensitivity floor? sensitivity, specificity, PPV, NPV at threshold
D6 Automation bias and over-reliance How do clinicians behave with it? not assessed by this harness; requires a human-factors study
D7 Post-deployment drift Is it decaying in service? PSI and KS on score distributions, AUROC decay against the sign-off set, with a power guard

Every headline metric carries a bootstrap confidence interval, resampled by patient when a --cluster-col is given, so that several cells from one film or images from one study are not treated as independent cases.

Not yet implemented and specified for the next build: AUPRC and the prevalence baseline, Wilson intervals, adaptive ECE and Spiegelhalter Z, recalibration fitting, the risk-coverage curve, out-of-distribution detection and decision-curve analysis.

What comes out

run_demo writes one JSON scorecard containing:

  • provenance: UTC timestamp, Python version, git commit, seed, SHA-256 of the input rows, and the methodology, engine and rubric versions (METH-0.2, engine 0.5.0, RUBRIC-0.4 in this release);
  • the raw metrics, probe findings, drift table and confidence intervals;
  • the D1 to D7 scorecard as Markdown, ready to paste into a report;
  • a mapping of the computed rows onto the reporting standards the method anchors to (ukaie/scoring/standards_map.py), derived from the resolved rows so an item can never claim evidence the run did not produce;
  • the engine's headline result and deployment recommendation.

A sample from the synthetic self-test is committed at ukaie/harness/sample_output/diagnostic_demo_scorecard.json.

How it is put together

Package Role
ukaie/scoring/ The scoring engine. Thresholds and mappings live in one file, constants.py, and every change to them is a version bump. diagnostics.py computes the metrics, engine.py scores findings, uncertainty.py does the bootstrap, standards_map.py maps rows to standards.
ukaie/harness/ The front end. adapters.py loads predictions, corpus.py builds the seeded synthetic corpus, probes.py runs the D3 and calibration probes and the deployment-site view, drift.py does D7, run_demo.py is the end-to-end entry point.
docs/ The methodology documents the engine stamps into every scorecard.

Tests sit beside the code (test_scoring.py, test_harness.py) and run with pytest.

Boundaries, stated plainly

  • The D3 shortcut metric is computed and reported but does not yet move the deployment gate (T3_ENABLED = False in constants.py) until the severity bands have been calibrated with a clinical advisor. The probe supplies the evidence; it does not flip the methodology switch.
  • D6 is not assessable from outputs and labels. The scorecard says so rather than leaving the row blank.
  • The synthetic corpus proves the detectors catch what they are built to catch. It proves nothing about any real model.
  • The harness scores what it is given. Whether the developer and deployment files really cross a deployment axis, and whether the labels are trustworthy, is the assessor's job and the method's §4 describes it.

Versions and reproducibility

Three version strings are stamped into every scorecard and bumped independently:

String Where Meaning
METH-0.2 constants.METHODOLOGY_VERSION_DIAGNOSTIC the published method a result was produced under
0.5.0 constants.SCORING_ENGINE_VERSION bumped on any threshold or logic change
RUBRIC-0.4 constants.RUBRIC_VERSION the scoring rubric; the comment beside it records what each revision changed and which published scores it affects

A third party with the same input file, seed and commit gets the same scorecard.

Where development happens

This repository is the public home of the harness. Day-to-day development happens in the company monorepo beside the evaluation platform, and the harness is exported here at every engine, rubric or methodology version. Issues and pull requests opened here are read and folded back; see CONTRIBUTING.md.

Licence

Code is licensed under Apache-2.0. The methodology documents in docs/ are licensed under CC BY 4.0. See NOTICE for attribution and the independence and non-endorsement statement. To cite, see CITATION.cff.

Contact

UK AI Evaluation Ltd, London. https://ukaievaluation.com · inquiries@ukaievaluation.com

About

Independent, reproducible evaluation of diagnostic and predictive-ML classifiers from model outputs and labels only. Standard-library Python. Implements the published METH-0.2 method.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages