devnotes.

Evaluation Metrics for Imbalanced Data

With imbalanced classes you need metrics that focus on the minority (positive) class.

The confusion matrix

Predicted PositivePredicted Negative
Actual PositiveTrue Positive (TP)False Negative (FN)
Actual NegativeFalse Positive (FP)True Negative (TN)

Key metrics

MetricFormulaMeaningUse when
PrecisionTP / (TP + FP)Of predicted positives, how many are correctFalse alarms are costly
Recall (Sensitivity)TP / (TP + FN)Of actual positives, how many were foundMissing a positive is costly (disease, fraud)
F1-score2PR / (P + R)Harmonic mean of precision and recallYou need a balance
F-betaWeighted F-scoreWeights recall (beta > 1) or precision (beta < 1)Custom trade-off
SpecificityTN / (TN + FP)Of actual negatives, how many are correctNegatives matter too
ROC-AUCArea under ROC curveRanking ability across thresholdsMild imbalance
PR-AUCArea under precision-recall curvePrecision/recall trade-offSevere imbalance
MCCCorrelation of prediction and truthA single balanced scoreRobust summary
Balanced accuracyMean of recall per classAccuracy that treats classes equallyQuick fix for accuracy

Computing the metrics

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import (classification_report, confusion_matrix, average_precision_score,
                             roc_auc_score, f1_score, matthews_corrcoef, balanced_accuracy_score)

model = RandomForestClassifier(random_state=42).fit(X_train, y_train)
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]

print(confusion_matrix(y_test, y_pred))
print(classification_report(y_test, y_pred, digits=3))

print("F1      :", round(f1_score(y_test, y_pred), 3))
print("PR-AUC  :", round(average_precision_score(y_test, y_prob), 3))
print("ROC-AUC :", round(roc_auc_score(y_test, y_prob), 3))
print("MCC     :", round(matthews_corrcoef(y_test, y_pred), 3))
print("Bal. acc:", round(balanced_accuracy_score(y_test, y_pred), 3))

Precision-recall curve

from sklearn.metrics import precision_recall_curve
import matplotlib.pyplot as plt

prec, rec, thr = precision_recall_curve(y_test, y_prob)
plt.plot(rec, prec)
plt.xlabel("Recall")
plt.ylabel("Precision")
plt.title("Precision-Recall curve")
plt.show()

Why PR-AUC over ROC-AUC for severe imbalance

ROC-AUC includes the huge number of true negatives, so it can look excellent even when the model finds few positives. PR-AUC ignores true negatives and reveals the real performance on the minority class.

Averaging in multi-class problems

AveragingBehaviour
macroAverage of per-class scores; every class counts equally
weightedAverage weighted by class size
microGlobal counts; dominated by large classes

Practical advice

  • Decide the metric before modeling, based on business cost.
  • Always look at the confusion matrix, not only a single number.
  • Use stratified cross-validation and report the mean and std of the chosen metric.
  • Compare against a naive baseline (DummyClassifier).
Evaluation Metrics for Imbalanced Data - Imbalanced Data | Data Preparation | DevNotes