Python Tutorial
AUC - ROC Curve
Judge a classifier across every decision threshold at once, independent of class balance.
Beyond a Single Threshold
Accuracy fixes the threshold at 0.5. But a probabilistic classifier can use any threshold, trading false positives against false negatives. The ROC curve plots this trade-off across all thresholds, and AUC (Area Under the Curve) summarizes it in one number.
- True Positive Rate (recall) = TP / (TP + FN) — on the y-axis.
- False Positive Rate = FP / (FP + TN) — on the x-axis.
Reading AUC
| AUC | Meaning |
|---|---|
| 1.0 | Perfect ranking |
| 0.9 | Excellent |
| 0.7–0.8 | Acceptable |
| 0.5 | No better than random guessing |
AUC is the probability that the model ranks a random positive example higher than a random negative one. It ignores the threshold and, unlike accuracy, is not fooled by class imbalance.
Computing AUC and Plotting the ROC
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, RocCurveDisplay
X, y = make_classification(n_samples=1000, weights=[0.9, 0.1], random_state=42)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42)
model = LogisticRegression(max_iter=1000).fit(X_train, y_train)
probs = model.predict_proba(X_test)[:, 1] # probability of the positive class
print("AUC:", round(roc_auc_score(y_test, probs), 3))
RocCurveDisplay.from_predictions(y_test, probs)
plt.plot([0, 1], [0, 1], "k--", label="random")
plt.legend()
plt.show()Feed AUC the predicted probabilities (or scores), not the 0/1 labels. Passing hard labels collapses the curve to a single point and gives a meaningless AUC.
Why It Beats Accuracy on Imbalanced Data
With 99% negatives, a model that always predicts "negative" scores 99% accuracy while being useless. Its AUC would be 0.5, exposing the failure. That is why AUC is the standard metric for fraud, disease, and churn detection.
Precision-Recall Curve for Rare Positives
When the positive class is very rare and you care mostly about it, the Precision-Recall curve and its average precision (AP) are often more informative than ROC-AUC.
from sklearn.metrics import average_precision_score, PrecisionRecallDisplay
print("Average precision:", round(average_precision_score(y_test, probs), 3))
PrecisionRecallDisplay.from_predictions(y_test, probs)
plt.show()Choosing an Operating Threshold
AUC evaluates every threshold, but in production you must pick one. Select it from the ROC/PR curve based on the costs of false positives vs false negatives.
from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y_test, probs)
# Youden's J: threshold that maximizes TPR - FPR
best = thresholds[np.argmax(tpr - fpr)]
print("suggested threshold:", round(best, 3))Best Practices
- Use probabilities/scores for AUC, never hard labels.
- Prefer AUC (or AP) over accuracy for imbalanced classification.
- Use the Precision-Recall curve when the positive class is rare and central.
- Choose the deployment threshold from business costs, not a default 0.5.
Try It Yourself
Exercise 1: Compute the AUC given true labels and predicted probabilities.
Show solution
from sklearn.metrics import roc_auc_score
y_true = [0, 0, 1, 1]
y_score = [0.1, 0.4, 0.35, 0.8]
print(round(roc_auc_score(y_true, y_score), 3)) # 0.75Exercise 2: A model has 99% accuracy but 0.5 AUC on imbalanced data. What does that tell you?
Show solution
It is no better than random at ranking positives — it likely just predicts the majority class every time. Accuracy is misleading here.
📘 Real-World Deep Dive
Knowing <strong>ML Auc Roc (scikit-learn)</strong> well is what turns scikit-learn from a curiosity into a daily tool — you'll reach for it in nearly every real project.
Real-Life Scenario
An end-to-end usage of ML Auc Roc that you'd actually see in a data pipeline or analytics notebook.
Real-Life Example
from sklearn.metrics import roc_auc_score
y_true = [0, 0, 1, 1]
scores = [0.1, 0.4, 0.35, 0.8]
print(round(roc_auc_score(y_true, scores), 3))Expected Output
(see source)Common mistakes
fitexpects numeric arrays;OneHotEncoder/LabelEncoderare easy to forget for categorical features.- Calling
predicton a model trained on unscaled data and then scaling inputs at inference time silently degrades accuracy. train_test_split(X, y)requires both arrays;train_test_split(X)for unsupervised learning slips past static checkers.- Treating ML Auc Roc as a black box without reading the docs — the API has subtle defaults that bite when you scale.
🚀 Performance & Best Practices
- Wrap preprocessing + estimator in a
Pipelinesofit/predictstay reproducible. - Use
joblib/picklefor serialising models, not the entire Python state. - For > 100 k rows, switch to
HistGradientBoostingClassifierorcuML. - When working with scikit-learn, prefer vectorised / batched operations over Python loops.
🧪 Try It Yourself
- Reproduce the snippet on a representative slice of your own data.
- Profile the snippet with
cProfileortimeitand find the single biggest improvement. - Generalise the snippet into a small, reusable function you can drop into future projects.