A.u.c. en Python et R : méthodes fiables pour calculer vos scores

L’AUC (Area Under the Curve) mesure l’aire sous la courbe ROC d’un modèle de classification binaire. Cette valeur, comprise entre 0 et 1, résume en un seul nombre la capacité du modèle à séparer les exemples positifs des exemples négatifs sur l’ensemble des seuils de décision possibles. Un score de 0,5 correspond à une prédiction aléatoire ; un score de 1,0 à une séparation parfaite.

Calculer l’AUC correctement en Python ou en R demande de choisir la bonne fonction et de comprendre ce que le score dit vraiment.

Ce que la courbe ROC construit avant le score AUC

La courbe ROC trace, pour chaque seuil de décision, le taux de vrais positifs (TPR) en ordonnée et le taux de faux positifs (FPR) en abscisse. Chaque point de la courbe correspond à un seuil différent appliqué aux scores bruts du modèle.

Le TPR (aussi appelé sensibilité ou recall) vaut TP / (TP + FN) : il mesure la proportion de positifs réels correctement détectés. Le FPR vaut FP / (FP + TN) : il mesure la proportion de négatifs réels incorrectement classés comme positifs. En faisant varier le seuil de 1 à 0, on trace la courbe complète.

L’AUC est ensuite calculée comme l’intégrale numérique de cette courbe, le plus souvent par la méthode des trapèzes. C’est ce que font les fonctions de calcul dans scikit-learn et dans les packages R dédiés.

Calculer l’AUC en Python avec scikit-learn

La bibliothèque scikit-learn propose deux fonctions distinctes : roc_auc_score pour un calcul direct à partir des scores bruts, et la combinaison roc_curve + auc pour tracer la courbe avant de calculer l’aire.

La méthode directe est la plus courante :

  • Séparer les données en ensemble d’entraînement et ensemble de test avec train_test_split avant tout calcul. Calculer l’AUC sur les données d’entraînement produit une valeur optimiste qui ne reflète pas les performances réelles du modèle.
  • Utiliser les scores de probabilité, pas les classes prédites. La fonction roc_auc_score attend un vecteur de scores continus (obtenu via predict_proba ou decision_function), pas un vecteur de 0 et 1.
  • Vérifier l’ordre des colonnes lors de l’appel à predict_proba : la colonne 1 correspond à la probabilité de la classe positive. Passer la colonne 0 par erreur inverse le score et donne une AUC inférieure à 0,5.

Un exemple minimal fonctionnel :

from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
model.fit(X_train, y_train)
scores = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, scores)

Pour tracer la courbe ROC et vérifier visuellement le résultat, on passe par roc_curve qui retourne trois vecteurs : FPR, TPR et les seuils correspondants. On calcule ensuite l’AUC avec la fonction auc(fpr, tpr).

Data scientist debout utilisant RStudio pour calculer un score AUC d'un modèle de classification dans un espace de travail moderne en open space

Calculer l’AUC en R : pROC et le package AUC

En R, deux packages couvrent la majorité des besoins : pROC et AUC (disponible sur CRAN). Les deux s’appuient sur la même logique de courbe ROC, mais diffèrent dans leur interface et leurs options.

Avec pROC, la fonction centrale est roc(), qui accepte un vecteur de labels et un vecteur de scores. Elle retourne un objet ROC dont on extrait l’AUC avec auc().

Un exemple minimal :

library(pROC)
roc_obj <- roc(y_test, scores)
auc(roc_obj)

Le package AUC (sur CRAN) propose une approche similaire avec la fonction auc(roc(scores, labels)). Il inclut aussi des métriques complémentaires comme la courbe précision-rappel via accuracy() et precision().

Un point pratique souvent ignoré : pROC calcule par défaut l’AUC dans le sens croissant des scores. Si vos scores sont inversés (une valeur faible indique la classe positive), précisez l’argument direction = ">" pour éviter un résultat erroné.

Interpréter l’AUC sans surestimer ce qu’elle mesure

L’AUC évalue le classement relatif des exemples, pas la qualité des probabilités produites par le modèle. Un modèle peut obtenir une AUC élevée tout en assignant des probabilités mal calibrées. Si ces scores servent à estimer un risque, une vérification de calibration s’impose en complément (courbe de fiabilité ou score de Brier).

Avec des classes très déséquilibrées, une bonne AUC ROC peut masquer une précision opérationnelle insuffisante. La courbe précision-rappel et l’average precision (calculable avec average_precision_score dans scikit-learn) apportent une lecture complémentaire utile dans ces cas.

Pour fixer un seuil de décision après avoir calculé l’AUC, on revient aux vecteurs FPR et TPR retournés par roc_curve ou roc(). Chaque point de la courbe correspond à un seuil exploitable selon les contraintes métier : minimiser les faux positifs, augmenter le rappel, ou trouver un équilibre via le point le plus proche du coin supérieur gauche.

Méthode de concordance : une alternative au calcul par trapèzes

La statistique de Wilcoxon-Mann-Whitney établit une équivalence mathématique entre l’AUC et la probabilité qu’un exemple positif tiré aléatoirement reçoive un score supérieur à un exemple négatif tiré aléatoirement. Cette interprétation probabiliste de l’AUC est utile pour communiquer la performance d’un modèle à un public non technique.

En pratique, cette équivalence signifie que l’AUC peut être calculée en comptant les paires concordantes parmi toutes les paires possibles, sans passer par la courbe ROC. Pour un grand nombre d’exemples, le calcul par trapèzes et le calcul par concordance donnent des résultats identiques.

Le calcul par concordance explicite peut être plus lent sur de grands jeux de données, mais il reste utile pour vérifier un résultat ou comprendre ce que l’AUC mesure concrètement. Pour un grand volume de calculs répétés, des implémentations optimisées (numba, data.table en R) peuvent réduire significativement la durée de traitement.

Les immanquables