How to Mock ROC AUC in Python
Compute ROC AUC from scratch in Python using pairwise comparisons between positive and negative score distributions, ideal for testing ML models without sklearn.
Python code
33 linesimport random
from math import comb
def mock_roc_auc(scores, labels):
"""Compute mock ROC AUC by simulating a classifier's score distribution."""
random.seed(42)
n = len(labels)
pos_scores = [scores[i] for i in range(n) if labels[i] == 1]
neg_scores = [scores[i] for i in range(n) if labels[i] == 0]
auc = sum(
1 if p > n_score else 0.5 if p == n_score else 0
for p in pos_scores
for n_score in neg_scores
) / (len(pos_scores) * len(neg_scores))
return auc
scores = [random.uniform(0, 1) for _ in range(10)]
labels = [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
auc = mock_roc_auc(scores, labels)
print(f"Mock ROC AUC: {auc:.4f} (scores={[round(s, 2) for s in scores]})")
# Also compute with rank-based method (Mann-Whitney U statistic equivalent)
scores2 = [0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0]
labels2 = [1, 1, 0, 1, 0, 0, 1, 0, 0, 0] # 4 positives, 6 negatives
auc2 = sum(
1 if scores2[i] > scores2[j] else 0.5 if scores2[i] == scores2[j] else 0
for i in range(len(labels2)) if labels2[i] == 1
for j in range(len(labels2)) if labels2[j] == 0
) / (sum(labels2) * (len(labels2) - sum(labels2)))
print(f"Rank-based AUC: {auc2:.4f}")
Output
Mock ROC AUC: 0.6250 (scores=[0.6394, 0.0250, 0.2750, 0.2230, 0.7365, 0.6767, 0.8922, 0.0869, 0.4219, 0.0298])
Rank-based AUC: 0.6667
How it works
The function computes AUC by comparing every positive-class score against every negative-class score. A positive score higher than a negative one contributes 1, ties contribute 0.5, and losses contribute 0 — the average of all comparisons is the AUC. The rank-based method uses the same pairwise logic but with a fixed, sorted score list to verify correctness. This 'from-scratch' approach avoids heavy dependencies and gives you full control over tie-handling in your ML evaluation pipeline.
Common mistakes
- Forgetting to handle ties (equal scores) — the 0.5 contribution is essential for correct AUC
- Using random scores without a fixed seed makes output non-reproducible in tests
- Dividing by zero when either class is empty in the dataset
- Confusing positive/negative label order — AUC depends on which class is treated as positive
Variations
- Use sklearn.metrics.roc_auc_score for a production-ready implementations when numpy/scikit-learn are available
- Implement using rank-based Mann-Whitney U statistic with sorted scores for O(n log n) complexity
Real-world use cases
- Unit testing model scoring logic without a full ML framework installed in CI environments
- Validating a custom scoring function's discrimination power during feature engineering iterations
- Quickly benchmarking a classic ML experiment in a lightweight serverless function where heavy dependencies are avoided.
Sponsored
More from ML engineering pipelines
- Bayesian Optimization in Python: A Simplified Mock Implementation medium
- Build a Data Helper Class in Python for ML Pipelines easy
- Build a Mock Random Forest Classifier in Python easy
- Champion Challenger Deployment Mock in Python easy
- Compare Model A vs Model B Metrics in Python easy
- Create a Minimal Great Expectations Suite Mock in Python easy
Keep learning
Related tutorials and quizzes for this topic.