Machine Learning : Comprendre la matrice de confusion
Apprenez ce qu'est une matrice de confusion, comment la construire en Python avec scikit-learn, la visualiser avec seaborn et en dériver la précision, le rappel et le F1-score.
Une matrice de confusion est un tableau qui résume les résultats de prédiction d'un modèle de classification en comparant les étiquettes réelles aux étiquettes prédites. C'est le point de départ pour calculer la précision, le rappel, le F1-score et la plupart des autres métriques de classification.
Ce chapitre couvre :
- Ce que signifient les quatre cellules (TP, FP, TN, FN) et pourquoi chacune est importante
- Comment calculer les métriques courantes à partir de ces cellules
- La construction et la visualisation d'une matrice de confusion en Python avec scikit-learn et seaborn
- Les matrices de confusion multi-classes
- Les pièges courants — en particulier sur les jeux de données déséquilibrés
Qu'est-ce qu'une matrice de confusion ?
Pour un classificateur binaire (deux classes possibles : positive et négative), la matrice de confusion est un tableau 2×2 :
| Prédit Positif | Prédit Négatif | |
|---|---|---|
| Réel Positif | Vrai Positif (TP) | Faux Négatif (FN) |
| Réel Négatif | Faux Positif (FP) | Vrai Négatif (TN) |
Chaque cellule comptabilise un type spécifique de résultat :
| Terme | Abréviation | Signification |
|---|---|---|
| Vrai Positif | TP | Le modèle prédit positif ; la réalité est positive ✓ |
| Vrai Négatif | TN | Le modèle prédit négatif ; la réalité est négative ✓ |
| Faux Positif | FP | Le modèle prédit positif ; la réalité est négative ✗ (erreur de type I) |
| Faux Négatif | FN | Le modèle prédit négatif ; la réalité est positive ✗ (erreur de type II) |
Un aide-mémoire rapide : le premier mot (Vrai / Faux) indique si la prédiction était correcte ; le second mot (Positif / Négatif) indique ce que le modèle a prédit.
Métriques dérivées de la matrice
Les quatre comptages alimentent toutes les métriques de classification standard :
| Métrique | Formule | Ce qu'elle mesure |
|---|---|---|
| Exactitude | (TP + TN) / (TP + TN + FP + FN) | Fraction globale des prédictions correctes |
| Précision | TP / (TP + FP) | Parmi toutes les prédictions positives, combien étaient correctes |
| Rappel (Sensibilité) | TP / (TP + FN) | Parmi tous les positifs réels, combien ont été trouvés |
| Spécificité | TN / (TN + FP) | Parmi tous les négatifs réels, combien ont été correctement exclus |
| F1-Score | 2 × Précision × Rappel / (Précision + Rappel) | Moyenne harmonique de la précision et du rappel |
Quand privilégier la précision par rapport au rappel
- Privilégiez le rappel lorsque manquer un cas positif est coûteux — dépistage médical, détection de fraude, filtres anti-spam qui doivent intercepter chaque message indésirable.
- Privilégiez la précision lorsque les fausses alarmes sont coûteuses — recommandations chirurgicales, signalement de documents juridiques, systèmes de notifications push.
- Le F1-score équilibre les deux et constitue la métrique par défaut lorsque le jeu de données est déséquilibré.
Exemple numérique pratique
Supposons qu'un modèle examine 100 patients pour une maladie :
- TP = 50 (patients malades correctement identifiés)
- FP = 5 (patients sains incorrectement signalés comme malades)
- FN = 10 (patients malades manqués)
- TN = 35 (patients sains correctement dégagés)
Calculs étape par étape :
Accuracy = (50 + 35) / 100 = 0.85 (85 %)
Precision = 50 / (50 + 5) ≈ 0.909 (90.9 %)
Recall = 50 / (50 + 10) ≈ 0.833 (83.3 %)
F1-Score = 2 × 0.909 × 0.833 / (0.909 + 0.833) ≈ 0.869 (86.9 %)Notez que l'exactitude (85 %) semble correcte, mais le rappel n'est que de 83 % — ce qui signifie que 10 patients malades sur 60 ont été manqués. Dans un contexte médical, cet écart est bien plus important que le chiffre d'exactitude affiché.
Construire une matrice de confusion en Python
Avec scikit-learn
sklearn.metrics fournit confusion_matrix() et un rapport textuel prêt à l'emploi via classification_report().
from sklearn.metrics import confusion_matrix, classification_report
# Ground-truth labels and model predictions
y_true = [1, 1, 0, 0, 1, 0, 1, 0, 1, 0]
y_pred = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1]
cm = confusion_matrix(y_true, y_pred)
print("Confusion Matrix:")
print(cm)
print()
print(classification_report(y_true, y_pred, target_names=["Negative", "Positive"]))confusion_matrix() renvoie un tableau NumPy. Par défaut, les lignes représentent les classes réelles et les colonnes les classes prédites (correspondant à la disposition du tableau ci-dessus). La disposition du tableau est :
[[TN FP]
[FN TP]]Calcul manuel des métriques
Vous pouvez extraire les quatre cellules et calculer les métriques vous-même pour vérification :
from sklearn.metrics import confusion_matrix
y_true = [1, 1, 0, 0, 1, 0, 1, 0, 1, 0]
y_pred = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1]
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
accuracy = (tp + tn) / (tp + tn + fp + fn)
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * precision * recall / (precision + recall)
print(f"TP={tp}, FP={fp}, FN={fn}, TN={tn}")
print(f"Accuracy : {accuracy:.3f}")
print(f"Precision: {precision:.3f}")
print(f"Recall : {recall:.3f}")
print(f"F1-Score : {f1:.3f}")Résultat attendu :
TP=4, FP=2, FN=1, TN=3
Accuracy : 0.700
Precision: 0.667
Recall : 0.800
F1-Score : 0.727Visualisation avec seaborn
Une carte thermique rend la matrice de confusion plus facile à lire, notamment pour les problèmes multi-classes :
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix
y_true = [1, 1, 0, 0, 1, 0, 1, 0, 1, 0]
y_pred = [1, 0, 0, 1, 1, 0, 1, 0, 1, 1]
cm = confusion_matrix(y_true, y_pred)
sns.heatmap(
cm,
annot=True,
fmt="d",
cmap="Blues",
xticklabels=["Negative", "Positive"],
yticklabels=["Negative", "Positive"],
)
plt.xlabel("Predicted label")
plt.ylabel("True label")
plt.title("Confusion Matrix")
plt.tight_layout()
plt.savefig("confusion_matrix.png", dpi=150)
plt.show()annot=True affiche le comptage à l'intérieur de chaque cellule ; fmt="d" les formate en entiers.
Matrices de confusion multi-classes
Lorsqu'il y a plus de deux classes, la matrice de confusion s'étend à une grille N×N. Chaque ligne représente toujours les classes réelles ; chaque colonne représente les classes prédites. Les cellules diagonales correspondent aux prédictions correctes ; les cellules hors diagonale correspondent aux erreurs.
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
import matplotlib.pyplot as plt
# Three classes: cat, dog, rabbit
y_true = ["cat", "dog", "rabbit", "cat", "dog", "rabbit",
"cat", "dog", "cat", "rabbit"]
y_pred = ["cat", "dog", "rabbit", "dog", "dog", "cat",
"cat", "rabbit", "cat", "rabbit"]
labels = ["cat", "dog", "rabbit"]
cm = confusion_matrix(y_true, y_pred, labels=labels)
print(cm)
disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=labels)
disp.plot(cmap="Blues")
plt.title("Multi-Class Confusion Matrix")
plt.tight_layout()
plt.savefig("cm_multiclass.png", dpi=150)
plt.show()ConfusionMatrixDisplay (ajouté dans scikit-learn 0.24) est une alternative pratique en une ligne à la carte thermique seaborn et ne nécessite aucune dépendance envers seaborn.
Pour les problèmes multi-classes, la précision et le rappel sont calculés par classe puis moyennés. classification_report() propose trois stratégies de moyennage :
macro— moyenne non pondérée entre les classes (traite toutes les classes de façon égale).weighted— moyenne pondérée par le support (nombre d'instances réelles par classe).micro— agrège TP/FP/FN sur toutes les classes avant la division (donne l'exactitude globale pour les jeux de données équilibrés).
Pièges courants
L'exactitude est trompeuse sur les jeux de données déséquilibrés
Considérons un jeu de données où 95 % des échantillons sont négatifs. Un modèle qui prédit toujours négatif atteint 95 % d'exactitude mais a un rappel nul — il ne détecte jamais un cas positif. La matrice de confusion révèle immédiatement cela : toute la première ligne (Réel Positif) sera composée uniquement de FN.
Associez toujours l'exactitude à la précision, au rappel ou au F1-score sur des données déséquilibrées. Consultez le chapitre Train/Test Split pour savoir comment créer une partition représentative, et le chapitre AUC-ROC Curve pour une métrique d'évaluation indépendante du seuil.
Choisir la mauvaise stratégie de moyennage
Utiliser le moyennage macro lorsque les classes sont très déséquilibrées gonfle le score des classes rares. Utilisez weighted pour une image réaliste de la qualité globale du modèle sur l'ensemble du jeu de données.
Oublier la normalisation
Les comptages bruts dépendent de la taille du jeu de données. Lorsque vous comparez des modèles entraînés sur des jeux de données de tailles différentes, normalisez la matrice en divisant chaque ligne par sa somme (passez normalize='true' à confusion_matrix()) :
cm_normalized = confusion_matrix(y_true, y_pred, normalize="true")
print(cm_normalized.round(2))Chaque ligne donne maintenant une somme de 1,0, montrant la fraction de chaque classe réelle prédite correctement.
Matrice de confusion vs. autres outils d'évaluation
| Outil | Idéal pour |
|---|---|
| Matrice de confusion | Comprendre les types spécifiques d'erreurs commises par un modèle |
| AUC-ROC Curve | Comparer des classificateurs sur tous les seuils de décision |
| Cross-Validation | Estimer à quel point la matrice se généralise aux données non vues |
| Grid Search | Ajuster les hyperparamètres à l'aide d'une métrique choisie (ex. F1-score) |
Points clés à retenir
- Une matrice de confusion décompose les prédictions en TP, FP, TN et FN — quatre comptages qui révèlent quelles erreurs un modèle commet, et pas seulement combien.
- L'exactitude seule est insuffisante ; vérifiez toujours la précision, le rappel et le F1-score, en particulier sur des données déséquilibrées.
- Utilisez
sklearn.metrics.confusion_matrix()pour le calcul et seaborn ouConfusionMatrixDisplaypour la visualisation. - Les matrices multi-classes suivent la même convention ligne = réel, colonne = prédit et s'étendent à N×N.
- Adaptez la stratégie de moyennage (
macro,weighted,micro) à la distribution des classes de votre jeu de données.