Accuracy, précision, rappel, F1
Pourquoi apprendre ça ?
L'accuracy n'est pas toujours la bonne métrique. Un détecteur de cancer qui dit "tout le monde est sain" a 99% d'accuracy si 1% de la population est malade — mais il est complètement inutile. La précision, le rappel, le F1, l'AUC-ROC et la courbe précision-rappel capturent des aspects complémentaires indispensables pour évaluer un classifieur réel sur des données déséquilibrées.
Analogie
Imagine un détecteur d'incendie. La précision : parmi toutes les alarmes, combien étaient de vrais incendies ? Le rappel : parmi tous les vrais incendies, combien ont déclenché une alarme ? F1 équilibre les deux. L'AUC-ROC, c'est la probabilité que le modèle classe un positif aléatoire mieux qu'un négatif aléatoire — une mesure globale indépendante du seuil choisi.
Matrice de confusion et métriques de base
Théorie
Pour une classification binaire, la matrice de confusion :
| | Prédit positif | Prédit négatif | |--|---------------|----------------| | Vrai positif | TP | FN | | Vrai négatif | FP | TN |
Métriques fondamentales :
Le F1 est la moyenne harmonique — il pénalise les déséquilibres extrêmes entre précision et rappel.
F_beta : quand les deux métriques ont des importances différentes :
- : rappel deux fois plus important (détection de maladies)
- : précision deux fois plus importante (filtrage spam)
Calcul des métriques en Python
import numpy as np
from sklearn.metrics import classification_report, f1_score
y_true = np.array([1, 1, 0, 1, 0, 0, 1, 0, 1, 0])
y_pred = np.array([1, 1, 0, 0, 0, 1, 1, 0, 1, 0])
TP = ((y_pred == 1) & (y_true == 1)).sum()
TN = ((y_pred == 0) & (y_true == 0)).sum()
FP = ((y_pred == 1) & (y_true == 0)).sum()
FN = ((y_pred == 0) & (y_true == 1)).sum()
print(f"Accuracy : {(TP+TN)/(TP+TN+FP+FN):.2%}")
print(f"Précision : {TP/(TP+FP):.2%}")
print(f"Rappel : {TP/(TP+FN):.2%}")
print(f"F1 : {2*TP/(2*TP+FP+FN):.2%}")
print(classification_report(y_true, y_pred,
target_names=['négatif', 'positif']))
Checkpoint
Un modèle de détection de fraude prédit 'pas de fraude' pour tous les exemples. Le dataset contient 1% de fraudes. Quelle est son accuracy ?
Macro vs micro averaging (multi-classes)
Théorie
Pour la classification à classes, il faut agréger les métriques par classe.
Macro averaging : calcule la métrique pour chaque classe séparément, puis fait la moyenne simple :
- Donne le même poids à chaque classe, quelle que soit sa fréquence
- Sensible aux performances sur les classes rares
- Recommandé pour les datasets déséquilibrés
Micro averaging : agrège d'abord tous les TP, FP, FN, puis calcule la métrique globale :
- Donne le même poids à chaque exemple — favorise les classes fréquentes
- Égale à l'accuracy pour la classification multi-classe exclusive
Weighted averaging : pondéré par le support (nombre d'exemples par classe) :
| Méthode | Poids | Quand l'utiliser | |---------|-------|-----------------| | Macro | Classes égales | Datasets déséquilibrés, classes rares importantes | | Micro | Exemples égaux | Datasets équilibrés, performance globale | | Weighted | Proportionnel | Rapport général équilibré |
Macro vs micro F1 en sklearn
from sklearn.metrics import f1_score, classification_report
import numpy as np
# 3 classes, dataset déséquilibré (classe 2 rare)
y_true = np.array([0, 0, 0, 0, 1, 1, 1, 2])
y_pred = np.array([0, 0, 1, 0, 1, 1, 0, 1])
print(f"F1 macro : {f1_score(y_true, y_pred, average='macro'):.4f}")
print(f"F1 micro : {f1_score(y_true, y_pred, average='micro'):.4f}")
print(f"F1 weighted : {f1_score(y_true, y_pred, average='weighted'):.4f}")
# macro pénalise fortement l'erreur sur la classe 2 rare
# micro est dominé par les classes 0 et 1 fréquentes
print(classification_report(y_true, y_pred))
Micro vs Macro sur datasets déséquilibrés
Sur un dataset avec 90% de classe 0, 9% de classe 1 et 1% de classe 2 : le micro F1 peut être élevé même si la classe rare est mal prédite (dominé par la classe 0). Le macro F1 sera pénalisé si la classe rare a un F1 proche de 0. Pour les problèmes où les classes rares sont importantes (diagnostic médical, détection d'anomalies), utilisez macro F1 ou une pondération personnalisée.
AUC-ROC et courbe précision-rappel
Théorie
Courbe ROC (Receiver Operating Characteristic) :
Pour chaque seuil , on calcule :
- TVP (Rappel) : — taux de vrais positifs
- TFP : — taux de faux positifs
La courbe ROC trace TVP en fonction de TFP en faisant varier de 1 à 0.
AUC-ROC (aire sous la courbe ROC) :
- : classifieur parfait
- : classifieur aléatoire (diagonale)
- : pire que le hasard
Interprétation probabiliste :
Courbe précision-rappel : trace la précision en fonction du rappel. L'aire est l'Average Precision (AP).
Quand utiliser AUC-ROC vs AP ?
- AUC-ROC : bon pour les datasets équilibrés
- AP : préféré pour les datasets très déséquilibrés (peu de positifs) — plus discriminant
AUC-ROC et Average Precision en Python
import numpy as np
from sklearn.metrics import (roc_auc_score, precision_recall_curve,
average_precision_score)
np.random.seed(42)
n = 500
y_true = np.random.binomial(1, 0.15, n) # 15% positifs
y_prob = y_true * 0.6 + np.random.beta(2, 5, n) * 0.4
auc = roc_auc_score(y_true, y_prob)
ap = average_precision_score(y_true, y_prob)
print(f"AUC-ROC : {auc:.4f}")
print(f"Average Precision : {ap:.4f}")
# Seuil optimal pour F1 via la courbe PR
precisions, rappels, seuils = precision_recall_curve(y_true, y_prob)
f1 = 2*precisions[:-1]*rappels[:-1]/(precisions[:-1]+rappels[:-1]+1e-8)
idx = f1.argmax()
print(f"Seuil F1 optimal : {seuils[idx]:.3f}")
print(f"Précision/Rappel : {precisions[idx]:.3f} / {rappels[idx]:.3f}")
Checkpoint
Quand le rappel est-il plus important que la précision ?
Checkpoint
Quelle est l'interprétation probabiliste de l'AUC-ROC ?
Checkpoint
Pour un dataset très déséquilibré (1% de positifs), quelle métrique est préférable à l'AUC-ROC ?
À retenir
- Accuracy trompeuse sur datasets déséquilibrés — utiliser F1, AUC ou AP
- Précision = TP/(TP+FP) ; Rappel = TP/(TP+FN) ; = moyenne harmonique des deux
- : favorise le rappel ; favorise la précision
- Macro F1 : même poids par classe (classes rares importantes) ; Micro F1 : même poids par exemple
- AUC-ROC = P(score positif > score négatif) — indépendant du seuil
- Average Precision (PR-AUC) : meilleure que AUC-ROC pour les datasets très déséquilibrés