Machine Learning Academy · Leçon

Métriques de classification : exactitude, précision, rappel et F1

Calculez les quatre métriques sur les mêmes prédictions et comprenez lesquelles privilégier selon le coût des faux positifs et des faux négatifs.

Leçon 1 sur 413 étapes

Métriques de classification : exactitude, précision, rappel et F1 est une leçon Machine Learning Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Machine Learning Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Machine Learning Academy comprend 4 leçons au total.

Certaines parties de cette leçon n'ont pas encore été traduites et s'affichent en anglais.

Why Accuracy Is Often Not Enough

Accuracy — the fraction of correct predictions — is the most intuitive metric, but it is misleading when classes are imbalanced. Consider a medical test for a disease that affects 1% of patients. A model that always predicts 'healthy' achieves 99% accuracy while being completely useless — it misses every actual disease case. In fraud detection, cancer screening, or rare event prediction, accuracy hides the model's failure to detect the rare but critical positive class. This is why we need metrics that separately measure performance on each class: precision, recall, and F1-score.

import numpy as np

# 1000 patients: 990 healthy, 10 sick
y_true = [0]*990 + [1]*10
y_pred_dummy = [0]*1000  # Always predict healthy

correct = sum(p == t for p, t in zip(y_pred_dummy, y_true))
accuracy = correct / len(y_true)
print(f'Dummy accuracy: {accuracy:.1%}')  # 99.0% -- misleadingly high!
print('But 0 sick patients correctly identified!')
print('This is why we need precision and recall.')

The Confusion Matrix: Ground Truth

The confusion matrix is the foundation of all classification metrics. For binary classification, it is a 2x2 table: True Positives (TP) — correctly predicted positive; True Negatives (TN) — correctly predicted negative; False Positives (FP) — predicted positive but actually negative (Type I error); False Negatives (FN) — predicted negative but actually positive (Type II error). Every classification metric is derived from some combination of these four numbers. Inspecting the raw confusion matrix reveals which type of error the model makes most.

from sklearn.metrics import confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

cm = confusion_matrix(y_true, y_pred)
print('Confusion Matrix:')
print(cm)
# [[TN, FP],
#  [FN, TP]]
TN, FP, FN, TP = cm.ravel()
print(f'TP={TP}, TN={TN}, FP={FP}, FN={FN}')

Accuracy: Simple but Limited

Accuracy = (TP + TN) / (TP + TN + FP + FN). It answers: of all predictions, what fraction were correct? Accuracy is a fair metric only when classes are roughly balanced and the costs of false positives and false negatives are similar. For example, handwritten digit recognition with ~10% of each digit class is balanced, making accuracy a reasonable measure. Use accuracy when: classes are balanced and all errors have equal cost. Avoid it when: classes are skewed (one class dominates) or false negatives cost more than false positives (or vice versa).

from sklearn.metrics import accuracy_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

acc = accuracy_score(y_true, y_pred)
print(f'Accuracy = {acc:.2f}')  # (TP+TN) / total

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
acc_manual = (TP + TN) / (TP + TN + FP + FN)
print(f'Manual: ({TP}+{TN}) / ({TP}+{TN}+{FP}+{FN}) = {acc_manual:.2f}')

Precision: Quality of Positive Predictions

Precision = TP / (TP + FP). It answers: of all the samples we predicted as positive, what fraction actually are positive? Precision is the metric to optimise when false positives are costly. In spam detection: a high-precision spam filter rarely marks legitimate email as spam. In drug testing: high precision means we rarely approve a drug that does not work. Low precision means many of our positive predictions are wrong — we are flooding users with false alarms. Precision tells you nothing about the false negatives — a model that only predicts one obvious case as positive has precision 1.0 but misses everything else.

from sklearn.metrics import precision_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

prec = precision_score(y_true, y_pred)
print(f'Precision = {prec:.2f}')

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
print(f'Manual: TP/(TP+FP) = {TP}/({TP}+{FP}) = {TP/(TP+FP):.2f}')
print('Of all PREDICTED positives, this fraction are truly positive.')

Recall: Coverage of Actual Positives

Recall = TP / (TP + FN) (also called Sensitivity or True Positive Rate). It answers: of all samples that actually are positive, what fraction did we find? Recall is the metric to optimise when false negatives are costly. In cancer screening: high recall means we identify most patients who actually have cancer. In fraud detection: high recall means we catch most fraudulent transactions. Low recall means we are missing too many actual positives — dangerous in medical or security contexts. Recall and precision are in tension: increasing one typically decreases the other.

from sklearn.metrics import recall_score, confusion_matrix
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

rec = recall_score(y_true, y_pred)
print(f'Recall = {rec:.2f}')

# Manual calculation
TN, FP, FN, TP = confusion_matrix(y_true, y_pred).ravel()
print(f'Manual: TP/(TP+FN) = {TP}/({TP}+{FN}) = {TP/(TP+FN):.2f}')
print('Of all ACTUAL positives, this fraction were correctly identified.')

The Precision-Recall Trade-Off

Precision and recall are inversely related when you adjust the classification threshold. As you lower the threshold (predict positive more aggressively), recall increases (you catch more actual positives) but precision decreases (more false positives get through). Raising the threshold has the opposite effect. There is no single threshold that simultaneously maximises both. Which metric to prioritise depends on the business problem: in email filtering, prioritise precision (do not annoy users with false spam alerts); in disease screening, prioritise recall (do not miss sick patients).

from sklearn.metrics import precision_score, recall_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np

X, y = load_breast_cancer(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=42)

clf = LogisticRegression(max_iter=10000)
clf.fit(X_tr, y_tr)
proba = clf.predict_proba(X_te)[:, 1]

for thresh in [0.3, 0.5, 0.7, 0.9]:
    y_pred = (proba >= thresh).astype(int)
    prec = precision_score(y_te, y_pred, zero_division=0)
    rec  = recall_score(y_te, y_pred)
    print(f'threshold={thresh}: precision={prec:.3f}, recall={rec:.3f}')

F1-Score: Harmonic Mean of Precision and Recall

F1-score = 2 * (Precision * Recall) / (Precision + Recall). The F1-score is the harmonic mean of precision and recall. Unlike the arithmetic mean, the harmonic mean punishes extreme values: a model with precision=1.0 and recall=0.0 gets F1=0, not 0.5. This makes F1 a fair aggregate metric that requires both precision and recall to be reasonably high. F1 is the standard metric for imbalanced text classification (NLP benchmarks always report it), fraud detection, and any problem where class imbalance makes accuracy misleading.

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

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

prec = precision_score(y_true, y_pred)
rec  = recall_score(y_true, y_pred)
f1   = f1_score(y_true, y_pred)

print(f'Precision = {prec:.3f}')
print(f'Recall    = {rec:.3f}')
print(f'F1-Score  = {f1:.3f}')
print(f'Manual F1 = 2 * ({prec:.3f} * {rec:.3f}) / ({prec:.3f} + {rec:.3f}) = {2*prec*rec/(prec+rec):.3f}')

Fbeta-Score: Weighted Precision-Recall Balance

The Fbeta score generalises F1 by introducing a parameter beta that controls how much to weight recall relative to precision: F_beta = (1 + beta^2) * Precision * Recall / (beta^2 * Precision + Recall). When beta=1, this is the standard F1 score. When beta=2 (F2), recall is weighted twice as much as precision — useful when missing positives is twice as costly as false alarms. When beta=0.5 (F0.5), precision is weighted more — useful in recommendation systems where accuracy of suggestions matters more than coverage.

from sklearn.metrics import fbeta_score
import numpy as np

y_true = [1, 0, 1, 1, 0, 0, 1, 0, 0, 1]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 0, 0]

for beta in [0.5, 1.0, 2.0]:
    score = fbeta_score(y_true, y_pred, beta=beta)
    print(f'F{beta:.1f} = {score:.3f}')

print()
print('beta=0.5: precision weighted 2x -> use when false alarms costly')
print('beta=1.0: balanced precision/recall -> standard F1')
print('beta=2.0: recall weighted 2x -> use when missing positives costly')

Multi-Class Averaging: Macro, Micro, and Weighted

For multi-class classification, you must aggregate per-class precision/recall/F1 into a single number. Macro average: compute metric for each class independently, then average — treats all classes equally regardless of size. Weighted average: same but weights by class support — gives larger classes more influence. Micro average: aggregate TP/FP/FN across all classes first, then compute — equivalent to accuracy for precision, recall, and F1 when there are no samples with multiple labels. Use macro for imbalanced datasets where small minority classes are important.

from sklearn.metrics import f1_score
import numpy as np

# Multi-class predictions
y_true = [0, 0, 1, 1, 2, 2, 2]
y_pred = [0, 1, 1, 1, 2, 0, 2]

print('Macro F1:    ', f1_score(y_true, y_pred, average='macro').round(3))
print('Micro F1:    ', f1_score(y_true, y_pred, average='micro').round(3))
print('Weighted F1: ', f1_score(y_true, y_pred, average='weighted').round(3))
print('Per-class F1:', f1_score(y_true, y_pred, average=None).round(3))
print()
print('Macro treats all classes equally (even rare ones)')
print('Weighted rewards correct prediction of common classes')

classification_report: All Metrics in One

classification_report() generates a formatted table showing precision, recall, F1-score, and support (number of true instances) for each class, plus macro/weighted averages. This is the standard output to include in any ML evaluation report. The 'support' column is especially important: a class with support=5 will have noisy precision/recall estimates and should be interpreted cautiously. Always check support values alongside F1 scores to assess metric reliability.

from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=42)

clf = RandomForestClassifier(random_state=42)
clf.fit(X_tr, y_tr)
y_pred = clf.predict(X_te)

print(classification_report(
    y_te, y_pred,
    target_names=load_iris().target_names
))

Balanced Accuracy for Imbalanced Classes

Balanced accuracy is the arithmetic mean of sensitivity (recall for each class). For binary classification: balanced_accuracy = (TPR + TNR) / 2 where TNR (True Negative Rate) = TN / (TN+FP). Unlike standard accuracy, balanced accuracy gives equal weight to each class regardless of how many samples it has. A model that always predicts the majority class gets balanced accuracy of 0.5 — correctly identifying it as no better than random. Use balanced accuracy when classes are imbalanced and you want a single metric that reflects performance on all classes equally, without the complexity of computing per-class metrics.

from sklearn.metrics import balanced_accuracy_score, accuracy_score
import numpy as np

# Imbalanced: 990 class 0, 10 class 1
y_true = np.array([0]*990 + [1]*10)
y_dummy = np.zeros(1000, dtype=int)  # Always predict class 0

acc_standard = accuracy_score(y_true, y_dummy)
acc_balanced = balanced_accuracy_score(y_true, y_dummy)

print(f'Standard accuracy: {acc_standard:.3f}')  # 99% -- misleading
print(f'Balanced accuracy: {acc_balanced:.3f}')  # 0.5 -- correctly shows no skill
print()
print('Balanced accuracy correctly penalises ignoring the minority class')

Quick Check

Test your understanding of Machine Learning with Python concepts from this lesson.

Lesson Recap

In this lesson you learned: accuracy is misleading for imbalanced classes — use the confusion matrix as ground truth, precision measures quality of positive predictions (minimise false positives) and recall measures coverage of actual positives (minimise false negatives), and F1-score harmonically combines both into a balanced metric. Next up we explore ROC curves and AUC-ROC for threshold-independent model evaluation.

Gratuit pour commencer

Apprends Python avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
30
Leçons
120

Questions Fréquemment Posées

La leçon « Métriques de classification : exactitude, précision, rappel et F1 » est-elle gratuite ?

Oui — le texte complet de « Métriques de classification : exactitude, précision, rappel et F1 » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Machine Learning Academy, passe à CoddyKit PRO. Le cours Machine Learning Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Métriques de classification : exactitude, précision, rappel et F1 » ?

Calculez les quatre métriques sur les mêmes prédictions et comprenez lesquelles privilégier selon le coût des faux positifs et des faux négatifs. Tu pratiques Machine Learning Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Machine Learning Academy ?

Aucune expérience préalable n'est requise. Machine Learning Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Métriques de classification : exactitude, précision, rappel et F1 » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Machine Learning Academy ?

Oui. Chaque leçon Machine Learning Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Métriques de classification : exactitude, précision, rappel et F1
  2. Courbes ROC et AUC-ROC
  3. Métriques de régression : MAE, MSE, RMSE et R-Squared
  4. Choisir la bonne métrique pour votre problème métier
← Retour à Machine Learning Academy