Le machine learning en partant de zéro · Leçon 2.4 · 11 sur 33 leçons prêtes · 12 min
Calibration : 0,8 veut-il dire 80 % ?
En bref
Un modèle peut bien trier et mal donner les pourcentages. Le Bayes naïf déclare 98 % et a raison à 88 %. La température corrige cela sans changer de décision.
Échauffement Deux questions de leçons précédentes. Une minute, sans jamais bloquer la leçon.
Dans la leçon 2.3, les courbes ROC et PR vérifiaient à quel point un modèle trie bien les biopsies. Elles ne demandaient jamais si les nombres du modèle sont vrais. Le modèle dit « 0,8 ». Cela veut-il dire que 80 % de ces biopsies sont malignes ? C’est la question de la calibration. Aujourd’hui, vous la vérifiez sur deux modèles et vous voyez qu’un seul nombre suffit parfois à la corriger, sans changer une seule décision.
Choisissez une réponse et votre degré de certitude.
Répondez pour débloquer le labo.
Labo interactif
Ce labo interactif fonctionne dans un navigateur avec JavaScript activé. Le texte qui l’entoure décrit ce qu’il montre.
Voir la réponse
Bonne réponse : Sur environ 88 %, soit 10 points de moins que ce qu’il promet
Il déclare en moyenne 98,3 % et a raison dans 88,3 % des cas : un écart de 10,0 points. 149 des 171 biopsies reçoivent une confiance supérieure à 99 %, et 5 d’entre elles sont des erreurs. La température T = 4,12 fait baisser le score de Brier de 0,100 à 0,071 sans changer une seule décision.
À vous de jouer
- Commencez par le Bayes naïf sans calibration. Où sont les cercles par rapport à la diagonale ? Combien de biopsies reçoivent une confiance supérieure à 99 %, et combien d’entre elles sont des erreurs ?
- Activez la température. Que deviennent les cercles, le score de Brier et le ROC AUC ? Combien de décisions ont changé ?
- Passez à la régression logistique et comparez-la sans calibration et avec température. Ce modèle avait-il besoin d’une correction ?
Une fois vérifié dans le lab, mettons un nom sur ce que vous voyez.
L’idée en quelques mots
Un modèle est calibré quand on peut prendre ses nombres au pied de la lettre : parmi les biopsies auxquelles il donne 0,8, environ 80 % sont malignes, et parmi celles à 0,1, environ 10 %. C’est ce que vérifie le diagramme de fiabilité. On répartit les biopsies en tranches selon la probabilité déclarée et, dans chaque tranche, on compte la part vraiment maligne. Un modèle calibré se trouve sur la diagonale. Des cercles sous la diagonale, à droite, signalent un excès de confiance.
Calibrer, ce n’est pas trier. Le ROC AUC de la leçon 2.3 demande seulement si une biopsie maligne reçoit un score plus élevé qu’une bénigne. Le Bayes naïf trie bien (ROC AUC 0,966, presque comme la régression logistique avec 0,969), mais ses pourcentages sont gonflés. Parmi les 55 biopsies auxquelles il donne au moins 0,9, il déclare en moyenne 99,6 %, et 89,1 % sont malignes.
Le score de Brier mesure les deux à la fois : la moyenne du carré de l’écart entre la probabilité déclarée et ce qui s’est passé (1 pour maligne, 0 pour bénigne). Plus bas, c’est mieux. L’ECE dit à quelle distance moyenne de la diagonale se trouvent les cercles.
Jak to policzono
- Biopsies : Breast Cancer Wisconsin (Diagnostic), UCI, licence CC BY 4.0. 569 biopsies, 10 mesures « mean » chacune.
- Découpage stratifié : 171 biopsies de validation (30 %) ; du reste, 266 pour apprendre et 132 pour ajuster la calibration. Ni le modèle ni la calibration ne voient les biopsies de validation.
- Modèles : Bayes naïf à loi normale (
GaussianNB), et standardisation plus régression logistique (C = 1). - Température : un seul nombre T, ajusté sur les 132 biopsies de calibration pour que la log-loss soit minimale. Diagramme et ECE : 10 tranches de 0,1.
Pourquoi ça marche
Le Bayes naïf suppose que les mesures d’une tumeur sont indépendantes les unes des autres. Dans ces données, elles ne le sont pas : le rayon, le périmètre et l’aire d’une tumeur disent presque la même chose. Le modèle compte donc plusieurs fois la même preuve et l’ajoute encore et encore au score, jusqu’à ce que sa confiance atteigne 99 % et plus. L’ordre des biopsies reste sensé, car une tumeur plus grande reçoit toujours un score plus élevé, mais les pourcentages montent trop vite.
La température divise le score du modèle avant la sigmoïde par un seul nombre T. Pour le Bayes naïf, T = 4,12 : chaque score devient plus de quatre fois plus petit. Diviser par un nombre positif ne change ni le signe d’un score ni l’ordre des biopsies. Aucune décision au seuil 0,5 ne change, et le ROC AUC reste à 0,966. Seuls les pourcentages changent : la confiance moyenne passe de 98,3 % à 91,1 %, le score de Brier de 0,100 à 0,071 et l’ECE de 0,101 à 0,055. Désormais, 34 biopsies reçoivent une confiance supérieure à 99 %, et aucune n’est une erreur.
La régression logistique est calibrée presque d’emblée : elle déclare 92,5 % et a raison dans 91,2 % des cas. Sa température vaut T = 0,93, proche de 1, et le score de Brier reste à 0,063. Ce n’est pas un hasard : la régression logistique apprend en faisant baisser la log-loss, c’est-à-dire précisément la pénalité pour des pourcentages mal donnés.
Ce n’est pas le hasard d’un seul découpage. Dans le code ci-dessous, la même expérience tourne sur 50 autres découpages : le Bayes naïf déclare en moyenne 98,5 % et a raison dans 91,2 % des cas, et la température fait baisser son score de Brier à chaque fois. Pour la régression logistique, la température ne change presque rien.
Erreur fréquente
Vrai ou faux : « un score de 0,8 veut dire 80 % de chances ». Faux, tant que vous ne l’avez pas vérifié. Un modèle donne un nombre entre 0 et 1, mais rien ne garantit que ce soit une probabilité au sens courant. Dans le lab, le Bayes naïf donne à 149 des 171 biopsies une confiance supérieure à 99 %, et 5 d’entre elles sont des erreurs. Si ces pourcentages étaient vrais, il y aurait parmi elles moins de deux erreurs. Ne lisez le score d’un modèle comme une probabilité qu’après avoir vérifié le diagramme de fiabilité sur des données que le modèle n’a pas vues.
Une mise en garde dans l’autre sens : la calibration n’améliore pas le tri. La température ne change ni le ROC AUC ni l’exactitude, et elle n’apporte rien à un modèle bien calibré : le score de Brier de la régression logistique reste à 0,063. La calibration est utile quand les nombres du modèle vont plus loin : vers un seuil fixé selon le coût des erreurs (leçon 2.6), vers une somme de risques, vers une conversation avec une patiente.
Quiz
Trois questions pour vérifier vos acquis. Choisissez une réponse ou dépliez la solution sous chaque question. Au clavier : les flèches choisissent, Entrée ou Espace valide.
À retenir
- La calibration demande si les pourcentages du modèle sont vrais ; le tri (ROC AUC) est une autre question.
- On vérifie la calibration avec un diagramme de fiabilité et le score de Brier, sur des données que le modèle n’a pas vues.
- Le Bayes naïf est trop sûr de lui, car il compte plusieurs fois la même preuve venue de mesures liées.
- La température corrige les pourcentages avec un seul nombre et ne change ni décision ni ROC AUC.
Pour aller plus loin : formule, code, pratique
Les maths
Diagramme de fiabilité : dans une tranche B de probabilités déclarées, on compare la moyenne déclarée conf(B) à la part de positifs acc(B). Un modèle calibré vérifie P(y = 1 | p) = p.
Brier = (1/n) · Σ (pᵢ − yᵢ)², et ECE = Σ_B (|B| / n) · |acc(B) − conf(B)|.
Température : le modèle donne un score z (un logit) et la probabilité vaut p = σ(z / T), où σ(z) = 1 / (1 + e^(−z)). On ajuste T sur une partie séparée des données en faisant baisser la log-loss. Quand T > 1, les pourcentages s’aplatissent. Le signe de z / T est celui de z, donc la décision p ≥ 0,5 (c’est-à-dire z ≥ 0) ne change pas.
Platt : p = σ(a · z + b), deux nombres au lieu d’un. Le décalage b peut changer des décisions : dans le lab, il en change 2 pour le Bayes naïf.
En code (Python)
La même expérience dans scikit-learn sur 50 découpages aléatoires (266 biopsies pour apprendre, 132 pour calibrer, 171 pour juger) : confiance moyenne, exactitude et score de Brier avant et après la température.
import numpy as np
from scipy.optimize import minimize_scalar
from scipy.special import expit
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import brier_score_loss
X, y = load_breast_cancer(return_X_y=True)
X, y = X[:, :10], 1 - y # les 10 mesures « mean », comme dans le lab ; 1 = maligne
def score(m, rows): # score du modèle avant la sigmoïde : log P(maligne) - log P(bénigne)
lp = m.predict_log_proba(X[rows])
return lp[:, 1] - lp[:, 0]
def run(model, seed): # 266 pour apprendre, 132 pour calibrer, 171 pour juger (validation)
rest, va = train_test_split(np.arange(len(y)), test_size=0.3, stratify=y, random_state=seed)
tr, ca = train_test_split(rest, test_size=1 / 3, stratify=y[rest], random_state=seed)
m = model.fit(X[tr], y[tr])
zc, zv = score(m, ca), score(m, va)
loss = lambda T: np.mean(np.logaddexp(0, -zc / T) * y[ca] + np.logaddexp(0, zc / T) * (1 - y[ca]))
T = minimize_scalar(loss, bounds=(0.05, 20), method="bounded").x # température : un seul nombre, ajusté sur la partie de calibration
p0, p1 = expit(zv), expit(zv / T)
conf, acc = np.maximum(p0, 1 - p0).mean(), ((p0 >= 0.5) == y[va]).mean()
same = ((p0 >= 0.5) == (p1 >= 0.5)).all() # diviser par T ne change jamais une décision
return conf, acc, brier_score_loss(y[va], p0), brier_score_loss(y[va], p1), T, same
for name, model in (("naive Bayes", GaussianNB()), ("logistic regression", make_pipeline(StandardScaler(), LogisticRegression()))):
r = np.array([run(model, s) for s in range(50)])
print(f"{name}, 50 splits: declares {r[:, 0].mean():.1%}, accuracy {r[:, 1].mean():.1%}; Brier {r[:, 2].mean():.3f} -> {r[:, 3].mean():.3f} with T = {r[:, 4].mean():.2f}; lower in {(r[:, 3] < r[:, 2]).sum()} of 50, decisions kept in {int(r[:, 5].sum())} of 50")
Sortie
naive Bayes, 50 splits: declares 98.5%, accuracy 91.2%; Brier 0.077 -> 0.061 with T = 3.86; lower in 50 of 50, decisions kept in 50 of 50
logistic regression, 50 splits: declares 93.4%, accuracy 93.5%; Brier 0.047 -> 0.047 with T = 0.94; lower in 17 of 50, decisions kept in 50 of 50
Les découpages diffèrent de ceux du lab, donc les nombres aussi : le Bayes naïf déclare en moyenne 98,5 % et a raison dans 91,2 % des cas. L’image est la même. La température fait baisser son score de Brier dans 50 découpages sur 50 sans changer de décision, alors qu’elle ne fait presque rien à la régression logistique : Brier 0,047 avant et après.
Télécharger le notebook (.ipynb). Ouvrez-le dans Jupyter ou importez-le dans Google Colab ; il télécharge lui-même les données manquantes.
Pour les praticiens
- Dans scikit-learn,
calibration_curve,CalibrationDisplayetbrier_score_lossvérifient la calibration, toujours sur des données que le modèle n’a pas vues. CalibratedClassifierCVla corrige (method="sigmoid"pour Platt,"isotonic"pour la régression isotonique) ; la température s’ajoute facilement à la main. La régression isotonique demande plus de données, car elle ajuste toute une fonction en escalier.- Ajustez la calibration sur une partie séparée des données ou dans la validation croisée, jamais sur les données dont le modèle a appris : là, le modèle paraît meilleur qu’il ne l’est.
- Des pourcentages calibrés comptent quand le nombre va plus loin : vers un seuil fixé selon le coût des erreurs (leçon 2.6), vers une somme de risques, vers une conversation avec une patiente. Quand seul l’ordre compte, le ROC AUC suffit.
Cela vous a-t-il aidé ?
Merci ! Cela nous aide à nous améliorer.
Aller plus loin dans l’Atlas
Articles de l’encyclopédie sur les notions de cette leçon :