🎯 F1-Score — Quand l'Accuracy te ment en pleine face ! 📊💥

Community Article Published January 16, 2026

📖 Définition

F1-Score = la métrique qui ne se fait pas avoir par les classes déséquilibrées ! L'Accuracy dit "99% correct !" mais ton modèle prédit juste "pas de cancer" à chaque fois. Le F1-Score dit "MENTEUR, tu as détecté 0% des cancers !" C'est la moyenne harmonique de la Précision et du Recall, la métrique qui compte vraiment.

Principe :

  • Moyenne harmonique de Précision et Recall
  • Range 0-1 : 0 = poubelle, 1 = parfait
  • Équilibre faux positifs et faux négatifs
  • Immunisé contre déséquilibre : impossible de tricher avec classe majoritaire
  • Métrique standard pour problèmes de classification déséquilibrés ! 🔥

Avantages / Inconvénients / Limites

Avantages

  • Détecte les fausses accuracy : 99% accuracy = sans valeur si F1 = 0.05
  • Nombre unique : combine Précision et Recall élégamment
  • Résistant au déséquilibre : marche super bien pour ratio 99:1
  • Standard industriel : médical, fraude, spam l'utilisent tous
  • Interprétable : 0.9 F1 = excellent, 0.5 F1 = médiocre

Inconvénients

  • Ignore vrais négatifs : se fiche des cas correctement rejetés
  • Pèse erreurs également : faux positif = faux négatif (pas toujours vrai)
  • Dur à interpréter seul : besoin de voir Précision ET Recall séparément
  • Pas différentiable : impossible d'utiliser directement comme loss
  • Dépend du seuil : seuil différent = F1 différent

⚠️ Limites

  • Focus binaire : multi-classe nécessite variantes (macro/micro/weighted F1)
  • Assume coût égal : faux positif ≠ faux négatif en réalité
  • Moyenne harmonique dure : une mauvaise métrique (P ou R) fait chuter F1
  • Pas d'info probabiliste : juste prédictions 0/1, perd la confiance
  • Parfois remplacé : AUC-ROC pour ranking, MCC pour très déséquilibré

🛠️ Tutorial pratique : Mon cas réel

📊 Setup

  • Tâche : Détection cancer depuis images médicales (très déséquilibré !)
  • Dataset : 10 000 images (9 900 sains, 100 cancer = 1%)
  • Modèle : ResNet-18 fine-tuné
  • Hardware : GTX 1080 Ti 11GB (batch size 64)
  • Config : epochs=50, lr=0.001, optimizer=Adam

📈 Résultats obtenus

Modèle naïf (prédit "pas de cancer" toujours) :
- Accuracy : 99.0% (a l'air incroyable !)
- Précision : 0.0 (indéfini, jamais prédit positif)
- Recall : 0.0 (détecté 0 sur 100 cancers)
- F1-Score : 0.0 ❌ (A EXPOSÉ LE MENSONGE !)

ResNet-18 baseline (sans balancing) :
- Accuracy : 98.5%
- Précision : 0.20 (20% des prédictions positives correctes)
- Recall : 0.15 (détecté 15 sur 100 cancers)
- F1-Score : 0.17 ❌ (terrible !)

Avec Class Weighting (ratio 1:99) :
- Accuracy : 95.2% (plus bas mais on s'en fiche)
- Précision : 0.65 (65% des prédictions positives correctes)
- Recall : 0.78 (détecté 78 sur 100 cancers)
- F1-Score : 0.71 ✅ (bien mieux !)

Avec Focal Loss + Oversampling :
- Accuracy : 94.8%
- Précision : 0.82 (82% des prédictions positives correctes)
- Recall : 0.85 (détecté 85 sur 100 cancers)
- F1-Score : 0.83 ✅🏆 (excellent !)

Performance GTX 1080 Ti :
- Batch size 64 : 9.8GB VRAM utilisés
- Temps entraînement : 180 it/s
- Total training : 45 minutes
- Tracking F1 : calcul temps réel sklearn

🧪 Test en conditions réelles

Détection Spam (90% non-spam, 10% spam) :

Modèle optimisé accuracy :
- Accuracy : 92%
- Précision : 0.45
- Recall : 0.38
- F1-Score : 0.41 ❌

Modèle optimisé F1 :
- Accuracy : 88%
- Précision : 0.78
- Recall : 0.82
- F1-Score : 0.80 ✅ (attrape 82% des spams !)

Détection Fraude (99.5% légitime, 0.5% fraude) :

Modèle naïf :
- Accuracy : 99.5% (prédit "légitime" toujours)
- F1-Score : 0.0 ❌ (attrape 0 fraude)

Modèle optimisé :
- Accuracy : 96.8%
- Précision : 0.75 (75% des alertes fraude sont réelles)
- Recall : 0.88 (attrape 88% des fraudes)
- F1-Score : 0.81 ✅

Multi-classe (10 classes, CIFAR-10) :
- Macro-F1 : 0.89 (F1 moyen sur toutes classes)
- Micro-F1 : 0.91 (pondéré par fréquence classe)
- Weighted-F1 : 0.90 (pondéré par support)

Verdict : 🎯 F1-SCORE = ESSENTIEL POUR CLASSES DÉSÉQUILIBRÉES


💡 Exemples concrets

Comprendre Précision, Recall, F1

Exemple diagnostic médical (100 patients, 10 ont le cancer)

Prédictions modèle :
- Prédit cancer : 12 patients
- A vraiment le cancer (parmi ces 12) : 8 patients
- Cancers ratés : 2 patients

Matrice de confusion :
                 Prédit Non    Prédit Oui
Vraiment Non        88            2         (90 sains)
Vraiment Oui         2            8         (10 cancer)

Vrai Positif (TP) : 8 (cancer correctement détecté)
Faux Positif (FP) : 2 (fausse alerte, sain marqué cancer)
Faux Négatif (FN) : 2 (cancer raté, cancer marqué sain)
Vrai Négatif (TN) : 88 (sain correctement identifié)

Accuracy = (TP + TN) / Total = (8 + 88) / 100 = 96% ✅
(a l'air bien mais trompeur !)

Précision = TP / (TP + FP) = 8 / (8 + 2) = 8/10 = 0.80
(80% des prédictions positives sont correctes)

Recall = TP / (TP + FN) = 8 / (8 + 2) = 8/10 = 0.80
(détecté 80% des cancers réels)

F1-Score = 2 × (Précision × Recall) / (Précision + Recall)
         = 2 × (0.80 × 0.80) / (0.80 + 0.80)
         = 2 × 0.64 / 1.60
         = 0.80 ✅

F1 = moyenne harmonique, punit déséquilibre entre P et R

Pourquoi la Moyenne Harmonique compte

Cas 1 : Précision et Recall équilibrés

Précision = 0.80, Recall = 0.80
F1 = 2 × (0.80 × 0.80) / (0.80 + 0.80) = 0.80 ✅

Moyenne arithmétique donnerait : (0.80 + 0.80) / 2 = 0.80
Même résultat quand équilibré !

Cas 2 : Déséquilibré (haute Précision, bas Recall)

Précision = 0.95, Recall = 0.30
(modèle très prudent, prédit rarement positif)

F1 = 2 × (0.95 × 0.30) / (0.95 + 0.30) = 0.46 ❌
(lourdement pénalisé !)

Moyenne arithmétique : (0.95 + 0.30) / 2 = 0.625
(cacherait le problème !)

Moyenne harmonique punit déséquilibre durement !

Cas 3 : Déséquilibré (basse Précision, haut Recall)

Précision = 0.30, Recall = 0.95
(modèle agressif, prédit souvent positif)

F1 = 2 × (0.30 × 0.95) / (0.30 + 0.95) = 0.46 ❌
(même pénalité que cas 2 !)

Besoin des DEUX métriques hautes pour bon F1 !

Variantes F1 Multi-classe

Exemple 3 classes (Classification animaux)

Classe "Chat" : Précision=0.90, Recall=0.85, F1=0.87
Classe "Chien" : Précision=0.80, Recall=0.90, F1=0.85
Classe "Oiseau" : Précision=0.70, Recall=0.60, F1=0.65

Macro-F1 (moyenne F1 par classe) :
= (0.87 + 0.85 + 0.65) / 3 = 0.79
(traite toutes classes également)

Support : Chat=100, Chien=150, Oiseau=50

Weighted-F1 (pondéré par fréquence classe) :
= (0.87×100 + 0.85×150 + 0.65×50) / 300
= (87 + 127.5 + 32.5) / 300
= 0.82
(classes communes comptent plus)

Micro-F1 (TP/FP/FN globaux) :
Total TP = 85 + 135 + 30 = 250
Total FP = 9 + 30 + 13 = 52
Total FN = 15 + 15 + 20 = 50

Précision = 250 / (250 + 52) = 0.828
Recall = 250 / (250 + 50) = 0.833
Micro-F1 = 2 × (0.828 × 0.833) / (0.828 + 0.833) = 0.83

Applications réelles

Diagnostic Médical 🏥

  • Détection cancer, screening maladies
  • F1 critique : rater cancer = fatal
  • Priorité Recall haut (attraper tous les cas)
  • Exemple : F1 = 0.85 minimum requis

Détection Fraude 💳

  • Fraude carte bancaire, assurances
  • Équilibre : attraper fraude vs fausses alertes
  • Coût faux positif < coût faux négatif
  • Cible : F1 = 0.80+

Filtrage Spam 📧

  • Détection spam email
  • Priorité Précision haute (pas bloquer vrais emails !)
  • Mais aussi Recall haut (attraper la plupart des spams)
  • Cible : F1 = 0.90+

Recherche d'Information 🔍

  • Moteurs de recherche, systèmes recommandation
  • Précision = résultats pertinents / total retournés
  • Recall = résultats pertinents / total pertinents
  • Cible : F1 = 0.75+

📋 Fiche mémo : F1-Score

🔍 Formules de base

Matrice de confusion :
                Prédit Négatif    Prédit Positif
Vraiment Négatif      TN                FP
Vraiment Positif      FN                TP

Accuracy = (TP + TN) / (TP + TN + FP + FN)
(trompeur pour classes déséquilibrées !)

Précision = TP / (TP + FP)
"Parmi prédictions positives, combien sont correctes ?"

Recall = TP / (TP + FN)
"Parmi positifs réels, combien avons-nous détectés ?"

F1-Score = 2 × (Précision × Recall) / (Précision + Recall)
OU
F1 = 2×TP / (2×TP + FP + FN)
(moyenne harmonique de Précision et Recall)

F-Beta Score (généralise F1) :
Fβ = (1 + β²) × (Précision × Recall) / (β² × Précision + Recall)

β=1 : F1 (poids égal)
β=2 : F2 (favorise Recall 2x)
β=0.5 : F0.5 (favorise Précision 2x)

⚙️ Variantes F1 Multi-classe

Macro-F1 :
- Calcule F1 par classe
- Moyenne (poids égal)
- Usage : quand toutes classes également importantes

Micro-F1 :
- Somme tous TP, FP, FN globalement
- Calcule Précision/Recall/F1 unique
- Usage : quand métrique type-accuracy nécessaire

Weighted-F1 :
- Calcule F1 par classe
- Pondère par fréquence classe (support)
- Usage : quand déséquilibre classe existe

🛠️ Guide d'interprétation

Interprétation F1-Score :
0.90 - 1.00 : Excellent 🏆
0.80 - 0.90 : Très Bon ✅
0.70 - 0.80 : Bon 👍
0.60 - 0.70 : Acceptable 😐
0.50 - 0.60 : Mauvais ❌
0.00 - 0.50 : Très Mauvais ❌❌

Trade-offs :
Haute Précision, Bas Recall :
- Modèle conservateur (prédit rarement positif)
- Peu fausses alertes, mais rate beaucoup de cas
- Exemple : F1=0.50 (P=0.95, R=0.35)

Basse Précision, Haut Recall :
- Modèle agressif (prédit souvent positif)
- Attrape la plupart des cas, mais beaucoup fausses alertes
- Exemple : F1=0.50 (P=0.35, R=0.95)

Équilibré :
- Précision et Recall hauts tous les deux
- Meilleure performance globale
- Exemple : F1=0.85 (P=0.85, R=0.85)

🛠️ Quand utiliser quoi

Utilise Accuracy quand :
✅ Classes équilibrées (50-50, 30-30-40, etc.)
✅ Toutes erreurs également coûteuses
✅ Tâche binaire simple avec classes similaires

Utilise F1-Score quand :
✅ Classes déséquilibrées (1:99, 10:90, etc.)
✅ Faux positifs ET faux négatifs comptent
✅ Médical, fraude, détection spam
✅ Besoin métrique unique pour comparer modèles

Utilise Précision quand :
✅ Faux positifs sont TRÈS coûteux
✅ Exemple : filtre spam (pas bloquer vrais emails !)
✅ Exemple : système recommandation (pas recommander mauvais items)

Utilise Recall quand :
✅ Faux négatifs sont TRÈS coûteux
✅ Exemple : détection cancer (pas rater cancer !)
✅ Exemple : détection fraude (attraper toute fraude)

Utilise AUC-ROC quand :
✅ Besoin métrique indépendante du seuil
✅ Qualité ranking compte (pas juste classification)
✅ Sorties probabilistes importantes

Utilise MCC (Matthews Correlation) quand :
✅ Déséquilibre extrême (0.1% classe positive)
✅ Besoin métrique la plus robuste
✅ Les quatre valeurs matrice confusion comptent

💻 Concept simplifié (code minimal)

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

class F1ScoreDemo:
    def calculate_metrics(self, y_true, y_pred):
        """Calcule toutes métriques depuis prédictions"""
        
        precision = precision_score(y_true, y_pred)
        recall = recall_score(y_true, y_pred)
        f1 = f1_score(y_true, y_pred)
        
        print(f"Précision : {precision:.3f}")
        print(f"Recall : {recall:.3f}")
        print(f"F1-Score : {f1:.3f}")
        
        return precision, recall, f1
    
    def manual_f1_calculation(self, y_true, y_pred):
        """Calcule F1 manuellement depuis matrice confusion"""
        
        tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
        
        print(f"\nMatrice de confusion :")
        print(f"TP={tp}, FP={fp}, FN={fn}, TN={tn}")
        
        precision = tp / (tp + fp)
        recall = tp / (tp + fn)
        f1 = 2 * (precision * recall) / (precision + recall)
        
        print(f"\nCalcul manuel :")
        print(f"Précision : {precision:.3f}")
        print(f"Recall : {recall:.3f}")
        print(f"F1-Score : {f1:.3f}")
        
        return f1
    
    def imbalanced_example(self):
        """Montre F1 sur dataset déséquilibré"""
        
        y_true = np.array([0]*95 + [1]*5)
        
        naive_pred = np.array([0]*100)
        print("Modèle naïf (prédit toujours 0) :")
        print(f"Accuracy : {(naive_pred == y_true).mean():.3f}")
        
        balanced_pred = np.array([0]*92 + [1]*4 + [0]*1 + [1]*3)
        print("\nModèle équilibré :")
        accuracy = (balanced_pred == y_true).mean()
        print(f"Accuracy : {accuracy:.3f}")
        self.calculate_metrics(y_true, balanced_pred)
    
    def multiclass_f1(self, y_true, y_pred):
        """Calcule F1 pour multi-classe"""
        
        print("Variantes F1 multi-classe :")
        
        macro_f1 = f1_score(y_true, y_pred, average='macro')
        print(f"Macro-F1 : {macro_f1:.3f}")
        
        micro_f1 = f1_score(y_true, y_pred, average='micro')
        print(f"Micro-F1 : {micro_f1:.3f}")
        
        weighted_f1 = f1_score(y_true, y_pred, average='weighted')
        print(f"Weighted-F1 : {weighted_f1:.3f}")
        
        print("\nRapport par classe :")
        print(classification_report(y_true, y_pred))

demo = F1ScoreDemo()

y_true = np.array([0, 0, 1, 1, 0, 1, 0, 1, 1, 0])
y_pred = np.array([0, 0, 1, 0, 0, 1, 1, 1, 1, 0])

demo.calculate_metrics(y_true, y_pred)
demo.manual_f1_calculation(y_true, y_pred)
demo.imbalanced_example()

Le concept clé : F1-Score est la moyenne harmonique de Précision et Recall. Il punit le déséquilibre entre les deux. Tu ne peux pas tricher en optimisant juste l'un ! Besoin des deux hauts pour bon F1. Parfait pour classes déséquilibrées où l'accuracy ment ! 🎯


📝 Résumé

F1-Score = moyenne harmonique de Précision et Recall ! La métrique qui ne se fait pas avoir par les classes déséquilibrées. Range 0-1, punit les modèles qui optimisent seulement Précision OU Recall. Essentiel pour médical, fraude, spam où déséquilibre classe est extrême (ratio 1:99). Variantes existent : Macro-F1 (moyenne par classe), Micro-F1 (global), Weighted-F1 (par fréquence). Sur GTX 1080 Ti, tracking F1 temps réel avec sklearn pendant entraînement. Ne fais pas confiance à l'accuracy seule ! 🔥


🎯 Conclusion

F1-Score est essentiel pour classification real-world où les classes sont déséquilibrées. L'Accuracy peut montrer 99% mais être inutile si le modèle prédit juste la classe majoritaire. F1-Score expose ce mensonge en forçant Précision et Recall à être hauts tous les deux. La moyenne harmonique est intentionnellement dure : une mauvaise métrique fait chuter F1. Les applications modernes (diagnostic médical, détection fraude, filtrage spam) reposent toutes sur F1 comme métrique principale. Variantes multi-classe (macro/micro/weighted) étendent F1 aux scénarios complexes. Rapporte toujours F1 avec accuracy pour évaluation honnête. Sur GTX 1080 Ti, sklearn calcule F1 en millisecondes ! 🏆📊


Questions/Réponses

Q : Mon modèle a 95% accuracy mais F1-Score seulement 0.30, qu'est-ce qui cloche ? R : Ton dataset est très déséquilibré et ton modèle triche en prédisant la classe majoritaire ! Exemple : 95% "pas cancer", 5% "cancer". Modèle prédit "pas cancer" toujours = 95% accuracy mais F1=0 car attrape 0 cancers. Solutions : (1) Class weighting dans fonction de perte, (2) Oversampling classe minoritaire (SMOTE), (3) Focal Loss pour focus hard examples, (4) Ajuster seuil décision (au lieu 0.5, utilise 0.3), (5) Utiliser F1 comme cible d'optimisation pendant entraînement !

Q : Dois-je optimiser pour Précision ou Recall ? R : Dépend du coût des erreurs ! (1) Haute Précision quand faux positifs coûteux (filtre spam : pas bloquer vrais emails, système légal : pas condamner innocent), (2) Haut Recall quand faux négatifs coûteux (détection cancer : pas rater cancer, détection fraude : attraper toute fraude), (3) Équilibré (F1) quand les deux comptent également. Utilise F-beta score : F2 favorise Recall 2x, F0.5 favorise Précision 2x. Ajuste seuil de décision pour échanger Précision contre Recall !

Q : Macro-F1 vs Micro-F1 vs Weighted-F1, lequel ? R : Macro-F1 : moyenne F1 par classe (poids égal). Utilise quand toutes classes également importantes. Micro-F1 : TP/FP/FN globaux, F1 unique. Utilise quand métrique type-accuracy nécessaire, dominé par classes fréquentes. Weighted-F1 : F1 par classe pondéré par fréquence. Utilise quand déséquilibre classe existe mais classes fréquentes comptent plus. Pour diagnostic médical (maladie rare), utilise Macro-F1 pour donner importance égale à classe rare. Pour classification générale, utilise Weighted-F1 !


🤓 Le saviez-vous ?

F1-Score a été développé dans les années 1960 dans le domaine de la recherche d'information pour évaluer les moteurs de recherche ! À l'époque, ils avaient besoin de mesurer à la fois la Précision ("les résultats sont-ils pertinents ?") et le Recall ("avons-nous trouvé tous les documents pertinents ?"). Le "F" signifie "F-measure" ou "F-score", nommé d'après F-beta la version généralisée. Fun fact : la moyenne harmonique a été choisie au lieu de la moyenne arithmétique car elle pénalise lourdement le déséquilibre—si Précision ou Recall est bas, F1 est bas ! C'était intentionnel : tu ne peux pas contourner la métrique en sacrifiant l'un pour l'autre. Dans les années 1990-2000, F1-Score a explosé en machine learning à mesure que les datasets devenaient plus déséquilibrés (détection spam, détection fraude). Aujourd'hui, les compétitions Kaggle utilisent souvent F1 comme métrique principale pour datasets déséquilibrés. Le challenge détection cancer 2019 requérait F1 > 0.85, considéré comme grade clinique ! Encore plus intéressant : les modèles GPT sont évalués en interne avec F1-Score niveau-token pour tâches comme reconnaissance entités nommées et question-answering. Le benchmark GLUE (compréhension langage) rapporte F1 pour plusieurs tâches. La détection d'objets moderne (YOLO, Faster R-CNN) utilise mAP (mean Average Precision) qui est étroitement lié au F1 ! 🎯📊🧠


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