MathQuest

Accuracy, précision, rappel, F1

⏱ ~10 min·+30 XP
💡

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 :

Accuracy=TP+TNTP+TN+FP+FN\text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}

Preˊcision=TPTP+FP(parmi les positifs preˊdits, combien sont vrais ?)\text{Précision} = \frac{TP}{TP + FP} \quad \text{(parmi les positifs prédits, combien sont vrais ?)}

Rappel=TPTP+FN(parmi les vrais positifs, combien sont deˊtecteˊs ?)\text{Rappel} = \frac{TP}{TP + FN} \quad \text{(parmi les vrais positifs, combien sont détectés ?)}

F1=2PreˊcisionRappelPreˊcision+Rappel=2TP2TP+FP+FN\boxed{F_1 = \frac{2 \cdot \text{Précision} \cdot \text{Rappel}}{\text{Précision} + \text{Rappel}} = \frac{2TP}{2TP + FP + FN}}

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 :

Fβ=(1+β2)PreˊcisionRappelβ2Preˊcision+RappelF_\beta = (1+\beta^2) \cdot \frac{\text{Précision} \cdot \text{Rappel}}{\beta^2 \cdot \text{Précision} + \text{Rappel}}

  • β=2\beta = 2 : rappel deux fois plus important (détection de maladies)
  • β=0,5\beta = 0{,}5 : 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 à K>2K > 2 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 :

F1macro=1Kk=1KF1kF1_{\text{macro}} = \frac{1}{K} \sum_{k=1}^K F1_k

  • 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 :

F1micro=2kTPk2kTPk+kFPk+kFNkF1_{\text{micro}} = \frac{2 \sum_k TP_k}{2 \sum_k TP_k + \sum_k FP_k + \sum_k FN_k}

  • 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) :

F1weighted=knkNF1kF1_{\text{weighted}} = \sum_k \frac{n_k}{N} F1_k

| 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 tt, on calcule :

  • TVP (Rappel) : TVP=TP/(TP+FN)TVP = TP/(TP+FN) — taux de vrais positifs
  • TFP : TFP=FP/(FP+TN)TFP = FP/(FP+TN) — taux de faux positifs

La courbe ROC trace TVP en fonction de TFP en faisant varier tt de 1 à 0.

AUC-ROC (aire sous la courbe ROC) :

  • AUC=1,0\text{AUC} = 1{,}0 : classifieur parfait
  • AUC=0,5\text{AUC} = 0{,}5 : classifieur aléatoire (diagonale)
  • AUC<0,5\text{AUC} < 0{,}5 : pire que le hasard

Interprétation probabiliste : AUC=P(score(positif)>score(neˊgatif))\text{AUC} = P(\text{score}(\text{positif}) > \text{score}(\text{négatif}))

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) ; F1F_1 = moyenne harmonique des deux
  • FβF_\beta : β>1\beta > 1 favorise le rappel ; β<1\beta < 1 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
Passer aux exercices →