A model-agnostic diagnostic toolkit for post-hoc evaluation of binary classifiers.
π Preprint: Quantifying Decision-Boundary Uncertainty in Binary Classifiers: The Ambiguity Range Framework
Standard metrics like AUC-ROC summarise global discriminative performance but say nothing about the local distribution of predicted probabilities near the decision boundary. A classifier with AUC = 0.90 may still assign probabilities clustered tightly around 0.5 for a large fraction of predictionsβinstances where the model is, operationally, guessing.
The Ambiguity Range Framework makes this indecision zone explicit and measurable through three complementary metrics.
| Metric | Symbol | What it measures |
|---|---|---|
| Ambiguity Mass | AA_Mass(Ξ΄) | Fraction of predictions inside the indecision interval β_Ξ΄ = [0.5βΞ΄, 0.5+Ξ΄] |
| Ambiguity Area over PΒ·R | AA_PR | How severely precisionΒ·recall degrades as the decision threshold varies |
| Ambiguity Area over Fβ | AA_F1 | How severely Fβ degrades across thresholds (generalises to F_Ξ²) |
All three metrics return a value in [0, 1] where lower = less ambiguous.
git clone https://github.com/drkianmaleki/ambiguity-framework.git
cd ambiguity-framework
pip install -e .
pip install -r requirements.txtfrom ambiguity_suite import compute_AAPR, compute_AAF1, compute_AAMass
# Ground-truth labels and predicted probabilities from any classifier
y_true = [0, 0, 1, 1, 0, 1]
y_prob = [0.1, 0.4, 0.6, 0.9, 0.5, 0.8]
# Global threshold-sensitivity metrics (delta-invariant)
print(compute_AAPR(y_true, y_prob)) # β float in [0, 1]
print(compute_AAF1(y_true, y_prob)) # β float in [0, 1]
# Local indecision zone metric (varies with delta)
print(compute_AAMass(y_true, y_prob, delta=0.10)) # interval [0.40, 0.60]
print(compute_AAMass(y_true, y_prob, delta=0.20)) # interval [0.30, 0.70]python main.py \
--data path/to/predictions.csv \
--y-true label_column \
--y-prob score_column \
--delta 0.05 0.10 0.20ambiguity-framework/
βββ ambiguity_suite/ β installable package (the three metrics)
βββ experiments/ β experiment runners and data loaders
β βββ _runner_base.py β shared LR / RF / XGBoost evaluation logic
β βββ run_all_real.py β run all six real-world datasets at once
β βββ run_synthetic.py β Gaussian mixture sweep
β βββ run_calibration_ablation.py β Platt / isotonic calibration study
β βββ run_bootstrap_ci_fast.py β 95% bootstrap CIs on key comparisons
β βββ run_entropy_comparison.py β entropy and margin uncertainty baselines
β βββ run_paired_tests.py β Wilcoxon signed-rank tests (10-fold CV)
β βββ run_aamass_tstar.py β AAMass at F1-optimal threshold t*
β βββ run_calibrated_aamass.py β calibrated vs raw AAMass for all datasets
β βββ plot_reliability.py β reliability diagrams (calibration curves)
β βββ plot_graphical_abstract.py β graphical abstract figure
β βββ configs/ β experiment_grid.yaml (all reproducible params)
βββ tests/ β 62 pytest tests (all passing)
βββ data/
β βββ raw/ β place downloaded CSVs here (see below)
β βββ processed/ β auto-generated pickle cache
βββ results/
βββ tables/ β experiment output CSVs
βββ figures/ β generated plots
See data/raw/README.md for download URLs.
Place the CSV files in data/raw/ before running any experiments.
| Dataset | Source | Rows |
|---|---|---|
| Heart Disease | Kaggle | 918 |
| UCI Credit Card | UCI ML Repository | 30,000 |
| Hospital Readmissions | Kaggle | 25,000 |
| NSL-KDD | Kaggle | 4,431 |
| BRFSS 2015 | Kaggle | 253,680 |
| Credit Card Fraud | Kaggle | 284,807 |
python experiments/run_all_real.py --force-reloadResults written to results/tables/real_summary.csv. Estimated runtime: ~25 minutes.
python experiments/run_synthetic.pyResults written to results/tables/synthetic_summary.csv. Estimated runtime: ~5 minutes.
python experiments/run_calibration_ablation.pyCompares raw vs Platt vs isotonic calibration across all classifiers and datasets.
Results written to results/tables/calibration_ablation_summary.csv.
python experiments/run_bootstrap_ci_fast.pyComputes 95% bootstrap CIs for AAMass and AUC on the four moderate-sized datasets.
Results written to results/tables/bootstrap_ci_fast.csv. Estimated runtime: ~10 minutes.
python experiments/run_entropy_comparison.pyCompares AAMass against predictive entropy and margin uncertainty.
Results written to results/tables/entropy_comparison_summary.csv.
python experiments/run_paired_tests.pyRuns 10-fold stratified cross-validation and applies two-sided Wilcoxon
signed-rank tests on fold-paired AAMass and AUC-ROC observations.
Results written to results/tables/paired_tests_summary.csv.
Estimated runtime: ~2 hours (all six datasets).
python experiments/run_aamass_tstar.pyEvaluates AAMass centred at the F1-optimal operating threshold t* for each
classifier and dataset. Demonstrates metric utility on imbalanced datasets
where the default 0.5 centre is suboptimal.
Results written to results/tables/aamass_tstar_summary.csv.
Estimated runtime: ~1 minute.
python experiments/run_calibrated_aamass.pyComputes Platt-scaled (calibrated) AAMass alongside raw AAMass for all six
datasets. Produces the dual raw/calibrated column in the main results table.
Results written to results/tables/calibrated_aamass_summary.csv.
Estimated runtime: ~5 minutes.
python experiments/plot_reliability.py --dataset readmissions
python experiments/plot_reliability.py --all # all six datasets
python experiments/plot_graphical_abstract.py # graphical abstractpytest tests/ -vAll 62 tests should pass. The test suite covers metric correctness, edge cases, boundary behaviour, imbalanced datasets, and input validation.
Ambiguity Area over Precision and Recall. Integrates P(t)Β·R(t) over all
thresholds and normalises against a prevalence-dependent random-classifier
baseline. delta is accepted for API consistency but does not affect the
result β use compute_AAMass to measure score density within an interval.
Ambiguity Area over F-beta. Same as AAPR but integrates the F_Ξ² score.
At beta=1.0 this is the standard Fβ; beta>1 weights recall more heavily.
Ambiguity Mass. Returns the fraction of predictions in β_Ξ΄ = [0.5βΞ΄, 0.5+Ξ΄]. Compute across a range of Ξ΄ values to trace an ambiguity profile for your classifier.
Utilities that return the bounds and full width of β_Ξ΄.
If you use this framework in your research, please cite:
@misc{maleki2026ambiguity,
author = {Maleki, Kian},
title = {The Ambiguity Range Framework: A Diagnostic Toolkit for Operational Evaluation of Binary Classifiers},
year = {2026},
note = {Manuscript under review}
}MIT License. See LICENSE for details.