🎯 Precision & Recall — Les métriques jumelles qui ne sont jamais d'accord ! ⚖️🔍

Community Article Published January 8, 2026

📖 Définition

Precision & Recall = les deux meilleurs ennemis de l'évaluation en machine learning ! Precision dit "de tout ce que j'ai prédit positif, combien l'était vraiment ?" Recall dit "de tous les positifs réels, combien j'en ai trouvé ?" C'est impossible de maximiser les deux en même temps. Haute précision = peu de fausses alertes. Haut recall = tout attraper (mais plein de fausses alertes) !

Principe :

  • Precision = TP / (TP + FP) = qualité des prédictions positives
  • Recall = TP / (TP + FN) = quantité de positifs trouvés
  • Trade-off : améliorer l'un, l'autre baisse
  • F1-Score = moyenne harmonique (2 × Precision × Recall) / (Precision + Recall)
  • Le contexte importe : filtre spam ≠ détection cancer ! 🧠

Avantages / Inconvénients / Limites

Avantages

  • Spécifique aux classes : montre performance par classe (contrairement accuracy)
  • Gère le déséquilibre : fonctionne avec 99% classe A, 1% classe B
  • Interprétable : sens business clair
  • Complémentaires : ensemble racontent l'histoire complète
  • Contrôle du seuil : ajustable selon besoins business

Inconvénients

  • Malédiction du trade-off : impossible de maximiser les deux simultanément
  • Dépend du seuil : changer seuil change métriques
  • Pas d'info classe négative : ignore vrais négatifs (TN)
  • Confusant : lequel prioriser ?
  • Besoin métrique unique : F1 tente de combiner mais perd nuance

⚠️ Limites

  • Focus binaire : conçu pour classification binaire
  • Problèmes d'agrégation : micro/macro/weighted averaging pour multi-classe
  • Contexte requis : precision=0.9 bon ou mauvais ? Ça dépend !
  • Pas comparable : precision=0.9 de modèles différents ≠ même performance
  • Ignore la confiance : prédire 51% vs 99% = pareil

🛠️ Tutorial pratique : Mon cas réel

📊 Setup

  • Modèle : ResNet-18 classificateur binaire (Chat vs Chien)
  • Dataset : 10k images (5k chats, 5k chiens) - équilibré
  • Hardware : GTX 1080 Ti 11GB (batch size 128)
  • Tâche : Classifier images comme chat (positif) ou chien (négatif)
  • Epochs : 50

📈 Résultats obtenus

Dataset équilibré (GTX 1080 Ti, ResNet-18) :

Seuil = 0.5 (défaut) :
- Accuracy : 96.5%
- Precision : 0.965 (96.5% des prédictions "chat" sont correctes)
- Recall : 0.967 (trouvé 96.7% des chats réels)
- F1-Score : 0.966
- Status : Équilibré, excellent ✅

Seuil = 0.9 (haute confiance uniquement) :
- Accuracy : 93.2%
- Precision : 0.988 (98.8% des prédictions "chat" sont correctes !)
- Recall : 0.878 (trouvé seulement 87.8% des chats)
- F1-Score : 0.930
- Status : Peu de fausses alertes, mais chats manqués ⚠️

Seuil = 0.2 (agressif) :
- Accuracy : 91.8%
- Precision : 0.920 (92% des prédictions "chat" correctes)
- Recall : 0.996 (trouvé 99.6% des chats !)
- F1-Score : 0.956
- Status : Attrape tous les chats, mais fausses alertes 🚨

Dataset déséquilibré (95% chiens, 5% chats) :
Sans ajustement de seuil :
- Accuracy : 95.8% (trompeur !)
- Precision : 0.612 (plein de fausses alertes)
- Recall : 0.872 (trouve la plupart des chats)
- F1-Score : 0.720
- Problème : Accuracy ment ! ❌

Avec ajustement de seuil (0.3) :
- Accuracy : 92.1%
- Precision : 0.785
- Recall : 0.924
- F1-Score : 0.849
- Meilleur équilibre ! ✅

🧪 Test en conditions réelles sur GTX 1080 Ti

Diagnostic médical (Détection cancer) :
- Dataset : 1000 patients (950 sains, 50 cancer)
- Modèle : DenseNet-121
- Batch size 64 : 9.2GB VRAM utilisés

Modèle A (seuil élevé 0.9) :
- Precision : 0.95 (95% des prédictions cancer correctes)
- Recall : 0.68 (trouvé seulement 68% des cancers)
- Manqué : 16 cas de cancer ! ❌ INACCEPTABLE

Modèle B (seuil bas 0.3) :
- Precision : 0.72 (72% des prédictions cancer correctes)
- Recall : 0.96 (trouvé 96% des cancers !)
- Fausses alertes : 266 sains → cancer
- Meilleur : fausse alerte > cancer manqué ✅

Détection spam (Filtre email) :
- Dataset : 50k emails (45k normaux, 5k spam)
- Modèle : BERT-base
- Batch size 32 : 10.1GB VRAM utilisés

Haute Precision (seuil 0.8) :
- Precision : 0.98 (98% emails flaggés sont spam)
- Recall : 0.71 (attrapé 71% du spam)
- Résultat : Peu de faux positifs (bons emails safe) ✅

Haut Recall (seuil 0.2) :
- Precision : 0.82 (82% emails flaggés sont spam)
- Recall : 0.95 (attrapé 95% du spam !)
- Résultat : Plein de bons emails dans spam ❌

Reconnaissance faciale (Système sécurité) :
- Dataset : 10k visages (1k autorisés, 9k non-autorisés)
- Modèle : FaceNet
- Batch size 128 : 8.7GB VRAM

Équilibré (seuil 0.5) :
- Precision : 0.89
- Recall : 0.87
- F1-Score : 0.88
- Temps d'entraînement : 2h sur GTX 1080 Ti ✅

Verdict : 🎯 PRECISION & RECALL = DÉCISION BUSINESS, PAS JUSTE DES MÉTRIQUES


💡 Exemples concrets

Matrice de confusion expliquée

                Prédit
                Chat   Chien
Réel    Chat     850    50   ← 900 chats réels
        Chien     30   870   ← 900 chiens réels

Vrais Positifs (TP) = 850 (chats correctement prédits)
Faux Positifs (FP) = 30 (chiens prédits comme chats)
Faux Négatifs (FN) = 50 (chats prédits comme chiens)
Vrais Négatifs (TN) = 870 (chiens correctement prédits)

Precision = TP / (TP + FP) = 850 / (850 + 30) = 0.966
"Sur 880 prédictions chat, 850 étaient vraiment des chats"

Recall = TP / (TP + FN) = 850 / (850 + 50) = 0.944
"Sur 900 chats réels, on en a trouvé 850"

F1-Score = 2 × (0.966 × 0.944) / (0.966 + 0.944) = 0.955

Scénarios du monde réel

Détection de cancer 🏥

Priorité : HAUT RECALL (attraper tous les cancers !)
Acceptable : Basse precision (fausses alertes okay)

Pourquoi ?
- Cancer manqué = patient meurt ❌❌❌
- Fausse alerte = test supplémentaire (gênant mais safe) ✅

Cible : Recall > 0.95, Precision > 0.70
Seuil : Bas (0.2-0.3) pour tout attraper

Filtre spam 📧

Priorité : HAUTE PRECISION (ne pas perdre emails importants !)
Acceptable : Bas recall (un peu de spam passe)

Pourquoi ?
- Faux positif = perd email important ❌
- Faux négatif = spam dans inbox (agaçant mais pas critique) ✅

Cible : Precision > 0.95, Recall > 0.70
Seuil : Haut (0.7-0.8) pour éviter fausses alertes

Détection de fraude 💳

Priorité : ÉQUILIBRÉ (les deux importent !)
Trade-off : Bloquer vraies transactions vs laisser passer fraude

Pourquoi ?
- Faux positif = client énervé ❌
- Faux négatif = argent perdu ❌

Cible : F1-Score > 0.85 (équilibre les deux)
Seuil : Moyen (0.4-0.6) avec revue humaine

Reconnaissance faciale (Déverrouiller téléphone) 📱

Priorité : HAUTE PRECISION (ne pas laisser entrer inconnus !)
Acceptable : Bas recall (proprio réessaie)

Pourquoi ?
- Faux positif = inconnu déverrouille téléphone ❌❌❌
- Faux négatif = proprio réessaie (gênant) ✅

Cible : Precision > 0.99, Recall > 0.80
Seuil : Très haut (0.9+) pour sécurité

Trade-off Precision-Recall

Imagine : Classificateur binaire avec scores de confiance

Seuil = 0.9 (très strict) :
→ Prédit "positif" seulement quand >90% sûr
→ Peu de prédictions = Haute Precision (rarement faux)
→ Manque beaucoup de positifs = Bas Recall (attrape peu)

Seuil = 0.5 (équilibré) :
→ Prédit "positif" quand >50% sûr
→ Precision et Recall modérés

Seuil = 0.1 (très loose) :
→ Prédit "positif" quand >10% sûr  
→ Beaucoup de prédictions = Basse Precision (plein de fausses alertes)
→ Attrape la plupart des positifs = Haut Recall (manque peu)

Visuel :
Seuil  Precision  Recall  F1
0.9    0.95       0.70    0.81
0.7    0.90       0.82    0.86
0.5    0.85       0.88    0.87 ← Meilleur F1
0.3    0.75       0.94    0.84
0.1    0.60       0.98    0.75

📋 Fiche mémo : Precision & Recall

🔍 Formules essentielles

Vrais Positifs (TP) : Correctement prédit positif
Faux Positifs (FP) : Incorrectement prédit positif
Faux Négatifs (FN) : Positifs réels manqués
Vrais Négatifs (TN) : Correctement prédit négatif

Precision = TP / (TP + FP)
"De toutes mes prédictions positives, quel % était correct ?"

Recall = TP / (TP + FN)
"De tous les positifs réels, quel % j'ai trouvé ?"

F1-Score = 2 × (Precision × Recall) / (Precision + Recall)
"Moyenne harmonique équilibrant les deux"

Accuracy = (TP + TN) / (TP + FP + FN + TN)
"Justesse globale (trompeur avec déséquilibre !)"

🛠️ Quand prioriser quoi

HAUTE PRECISION nécessaire :
✅ Filtre spam (ne pas perdre emails importants)
✅ Alertes sécurité (réduire fausses alertes)
✅ Recommandations produits (ne pas agacer utilisateurs)
✅ Ciblage pub (gaspiller argent sur mauvaise audience)
→ Utilise seuil élevé (0.7-0.9)

HAUT RECALL nécessaire :
✅ Diagnostic médical (attraper toutes les maladies)
✅ Détection fraude (attraper toute la fraude)
✅ Systèmes de sécurité (attraper tous les dangers)
✅ Moteurs de recherche (montrer tous résultats pertinents)
→ Utilise seuil bas (0.2-0.4)

ÉQUILIBRÉ (F1) nécessaire :
✅ Classification générale
✅ Prédiction churn client
✅ Contrôle qualité
✅ Classification documents
→ Utilise seuil moyen (0.4-0.6)

⚙️ Averaging multi-classe

Micro-averaging :
- Regroupe tous TP, FP, FN ensemble
- Calcule une seule Precision/Recall
- Pondère par fréquence des classes
- Bon pour datasets déséquilibrés

Macro-averaging :
- Calcule Precision/Recall par classe
- Les moyenne (poids égal)
- Traite toutes les classes également
- Bon pour importance équilibrée

Weighted-averaging :
- Calcule Precision/Recall par classe
- Pondère par fréquence classe
- Équilibre fréquence et importance
- Choix le plus commun

Exemple (3 classes) :
Classe A : Precision=0.9, Recall=0.8 (100 samples)
Classe B : Precision=0.7, Recall=0.9 (50 samples)
Classe C : Precision=0.6, Recall=0.7 (10 samples)

Macro : (0.9+0.7+0.6)/3 = 0.73
Weighted : (0.9×100 + 0.7×50 + 0.6×10)/160 = 0.81

💻 Concept simplifié (code minimal)

import numpy as np
from sklearn.metrics import precision_score, recall_score, f1_score
from sklearn.metrics import confusion_matrix, classification_report

class PrecisionRecallDemo:
    def basic_example(self):
        """Calcul basique Precision & Recall"""
        
        # Labels vrais (réels)
        y_true = np.array([1, 1, 1, 1, 0, 0, 0, 0])
        
        # Prédictions
        y_pred = np.array([1, 1, 1, 0, 0, 0, 1, 0])
        
        # Calcul métriques
        precision = precision_score(y_true, y_pred)
        recall = recall_score(y_true, y_pred)
        f1 = f1_score(y_true, y_pred)
        
        print(f"Precision : {precision:.3f}")
        print(f"Recall : {recall:.3f}")
        print(f"F1-Score : {f1:.3f}")
        
        # Matrice de confusion
        cm = confusion_matrix(y_true, y_pred)
        print(f"\nMatrice de confusion :\n{cm}")
    
    def threshold_adjustment(self):
        """Ajuster seuil pour trader Precision vs Recall"""
        
        # Probabilités prédites
        y_probs = np.array([0.9, 0.8, 0.6, 0.4, 0.3, 0.2, 0.7, 0.1])
        y_true = np.array([1, 1, 1, 1, 0, 0, 0, 0])
        
        thresholds = [0.9, 0.7, 0.5, 0.3]
        
        print("Seuil  Precision  Recall  F1")
        for thresh in thresholds:
            y_pred = (y_probs >= thresh).astype(int)
            
            prec = precision_score(y_true, y_pred)
            rec = recall_score(y_true, y_pred)
            f1 = f1_score(y_true, y_pred)
            
            print(f"{thresh}      {prec:.3f}      {rec:.3f}   {f1:.3f}")
    
    def imbalanced_dataset(self):
        """Precision/Recall sur données déséquilibrées"""
        
        # 95% classe 0, 5% classe 1
        y_true = np.array([0]*950 + [1]*50)
        
        # Modèle naïf prédisant tout 0
        y_pred_naive = np.array([0]*1000)
        
        # Meilleur modèle
        y_pred_better = np.array([0]*920 + [1]*80)
        
        print("Modèle naïf (prédit tout 0) :")
        print(f"Accuracy : {(y_pred_naive == y_true).mean():.3f}")
        print(f"Recall : {recall_score(y_true, y_pred_naive):.3f}")
        
        print("\nMeilleur modèle :")
        print(f"Accuracy : {(y_pred_better == y_true).mean():.3f}")
        prec = precision_score(y_true, y_pred_better)
        rec = recall_score(y_true, y_pred_better)
        print(f"Precision : {prec:.3f}")
        print(f"Recall : {rec:.3f}")
        print(f"F1-Score : {f1_score(y_true, y_pred_better):.3f}")
    
    def multi_class_example(self):
        """Precision & Recall multi-classe"""
        
        y_true = np.array([0, 0, 1, 1, 2, 2, 0, 1, 2])
        y_pred = np.array([0, 1, 1, 1, 2, 0, 0, 1, 2])
        
        # Métriques par classe
        print("Micro-average :")
        print(f"Precision : {precision_score(y_true, y_pred, average='micro'):.3f}")
        
        print("\nMacro-average :")
        print(f"Precision : {precision_score(y_true, y_pred, average='macro'):.3f}")
        
        print("\nWeighted-average :")
        print(f"Precision : {precision_score(y_true, y_pred, average='weighted'):.3f}")
        
        print("\nRapport détaillé :")
        print(classification_report(y_true, y_pred))

# Exécution exemples
demo = PrecisionRecallDemo()
demo.basic_example()
demo.threshold_adjustment()
demo.imbalanced_dataset()
demo.multi_class_example()

Le concept clé : Precision demande "quand je dis oui, ai-je généralement raison ?" Recall demande "de tous les oui réels, combien j'en ai trouvé ?" Tu ne peux pas maximiser les deux ! C'est une décision business basée sur coût des faux positifs vs faux négatifs ! 🎯


📝 Résumé

Precision & Recall = métriques complémentaires pour évaluation classification ! Precision = qualité des prédictions positives (TP / positifs prédits). Recall = quantité de positifs trouvés (TP / positifs réels). Trade-off : impossible de maximiser les deux. F1-Score = moyenne harmonique équilibrant les deux. Le contexte importe : détection cancer nécessite haut recall, filtre spam nécessite haute precision. Réglage seuil sur GTX 1080 Ti : ajuste selon besoins business ! ⚖️🔍


🎯 Conclusion

Precision & Recall sont fondamentales pour comprendre performance classificateur au-delà de la simple accuracy. Elles révèlent quel type d'erreurs ton modèle fait. Le trade-off entre elles te force à prendre des décisions business : un faux positif est-il pire qu'un faux négatif ? Diagnostic médical : priorise recall (attraper toutes les maladies). Filtre spam : priorise precision (ne pas perdre emails importants). F1-Score fournit une métrique unique quand tu veux équilibre, mais regarde toujours les deux individuellement ! Sur GTX 1080 Ti, entraînement avec réglage seuil prend même temps mais te donne contrôle sur le trade-off. Rappelle-toi : le contexte est tout ! 🏆⚖️


Questions/Réponses

Q : Mon modèle a 95% d'accuracy mais performe terriblement. Qu'est-ce qui cloche ? R : Problème de déséquilibre de classes ! Accuracy est trompeur quand classes déséquilibrées. Exemple : 95% classe A, 5% classe B. Un modèle bête prédisant "toujours A" obtient 95% accuracy mais 0% recall pour classe B ! Vérifie toujours Precision & Recall pour chaque classe. Utilise F1-Score ou matrice de confusion pour voir l'image complète. Sur données déséquilibrées, considère weighted loss, oversampling classe minoritaire, ou focal loss !

Q : Comment choisir le bon seuil pour mon classificateur binaire ? R : Décision business ! Étapes : (1) Plot courbe Precision-Recall à différents seuils, (2) Identifie coût du faux positif vs faux négatif (exemple : faux négatif en cancer = mort, faux positif = test supplémentaire), (3) Choisis seuil qui minimise coût business. Règle générale : médical/sécurité = seuil bas (haut recall), spam/sécurité = seuil haut (haute precision), général = 0.5 (équilibré). Teste sur validation set avec GTX 1080 Ti pour voir les trade-offs !

Q : F1-Score, Precision, ou Recall - lequel dois-je optimiser ? R : Dépend de ton problème ! Optimise : (1) Recall si faux négatifs sont catastrophiques (cancer, fraude, sécurité), (2) Precision si faux positifs sont coûteux (spam, décisions légales, actions chères), (3) F1-Score si les deux importent également (classification générale, coûts inconnus). N'optimise jamais accuracy sur données déséquilibrées ! Pour multi-objectif, utilise weighted F-beta score : Fβ = (1+β²) × (Precision×Recall) / (β²×Precision + Recall), où β>1 favorise recall, β<1 favorise precision !


🤓 Le saviez-vous ?

Precision & Recall viennent de la recherche d'information dans les années 1950-60 quand les chercheurs construisaient des systèmes de recherche pour articles scientifiques ! Le problème : étant donné une requête comme "machine learning", quels documents doit-on retourner ? Recall mesurait "a-t-on trouvé tous les documents pertinents ?" tandis que Precision mesurait "les documents retournés sont-ils vraiment pertinents ?" Le trade-off était brutal : retourner tous les documents = 100% recall mais precision terrible. Retourner un seul match parfait = 100% precision mais recall terrible ! Fun fact : le F1-Score (moyenne harmonique) a été choisi plutôt que moyenne arithmétique car il punit les métriques déséquilibrées plus fort. Exemple : Precision=1.0, Recall=0.1 donne Arithmétique=0.55 mais F1=0.18 (plus réaliste) ! Le boom du deep learning moderne a redécouvert ces métriques dans les années 2010 quand accuracy a échoué sur datasets déséquilibrés comme imagerie médicale (99% sain, 1% cancer). Un classificateur prédisant "toujours sain" obtenait 99% accuracy mais était inutile ! Precision/Recall révélaient la vérité. Aujourd'hui, chaque compétition ML majeure (Kaggle, ImageNet, COCO) utilise F1 ou mAP (mean Average Precision). Même l'évaluation de GPT-4 utilise Precision/Recall pour tâches spécifiques comme extraction d'entités ! Les métriques qui ont commencé avec les catalogues de bibliothèques évaluent maintenant des modèles à milliards de paramètres ! 📚🧠⚡


Théo CHARLET

Étudiant TSSR - Spécialisation IA/ML

Créateur d'AG-BPE (Attention-Guided Byte-Pair Encoding)

🔗 LinkedIn: https://www.linkedin.com/in/théo-charlet

🚀 En recherche de stage

🔗 Site Web: https://rdtvlokip.fr

Community

Sign up or log in to comment