Arbitrez le dilemme biais-variance
Au chapitre précédent, vous avez vu qu’agrandir l’espace d’hypothèses réduit l’erreur d’approximation mais augmente l’erreur d’estimation. C’est une belle idée… mais ces deux erreurs font intervenir et , que l’on ne connaît jamais. Comment raisonner concrètement ?
Le dilemme biais-variance (bias-variance dilemma) répond à cette question pour la régression avec perte quadratique. Il découpe l’erreur d’une machine apprise en trois morceaux lisibles, que l’on peut mesurer par simulation et sur lesquels on sait agir. Notre fil rouge reste le salaire prédit à partir du GPA, avec la population du chapitre 3 : un salaire moyen qui plafonne, , et un bruit de variance .
Le biais, une notion venue de la statistique
Section intitulée « Le biais, une notion venue de la statistique »Le mot « biais » ne vient pas de l’apprentissage automatique, mais de la théorie de l’estimation. Vous voulez connaître une quantité de la population, par exemple le salaire moyen de tous les diplômés. Vous la calculez sur un échantillon et obtenez , un estimateur. Comme l’échantillon est aléatoire, l’est aussi : avec d’autres diplômés, vous auriez obtenu une autre valeur.
Le biais mesure l’erreur systématique de l’estimateur :
où est la valeur moyenne de l’estimateur si l’on refaisait l’expérience sur un très grand nombre d’échantillons.
- Un biais négatif signifie que l’estimateur sous-estime en moyenne.
- Un biais positif signifie qu’il surestime en moyenne.
- Un estimateur de biais nul est dit sans biais.
La variance mesure, elle, la dispersion de l’estimateur d’un échantillon à l’autre. Et l’erreur quadratique moyenne se décompose exactement en ces deux morceaux :
La réponse classique des statisticiens au choix d’un estimateur est l’estimateur sans biais de variance minimale (minimum variance unbiased estimator, MVUE) : parmi tous les estimateurs sans biais, prendre celui qui varie le moins. Cette réponse est élégante, mais elle n’est pas toujours la meilleure au sens de l’erreur totale, et c’est là que naît le dilemme.
Biais et variance d’une machine apprise
Section intitulée « Biais et variance d’une machine apprise »Transposons. La machine apprise est, elle aussi, un estimateur : elle estime à partir de l’échantillon . Pour un GPA fixé, sa prédiction change d’un échantillon à l’autre. On définit donc, en chaque point :
- désigne la moyenne sur tous les échantillons de taille que l’on aurait pu tirer ;
- est donc la prédiction moyenne en , celle d’une « machine moyenne » ;
- le biais compare cette machine moyenne à la vérité ;
- la variance mesure à quel point la prédiction en bouge quand l’échantillon change.
Si le salaire s’écrit en , avec un bruit de moyenne nulle, de variance et indépendant de l’échantillon d’apprentissage, l’erreur quadratique attendue en se décompose en trois termes (exercice 3) :
Chaque terme se relie à ce que vous connaissez déjà.
- est l’erreur irréductible : c’est le risque de Bayes du chapitre 3. Aucune machine n’y échappe.
- Le biais au carré reflète l’erreur d’approximation : même en moyennant sur tous les échantillons possibles, un espace trop pauvre reste loin de .
- La variance reflète l’erreur d’estimation : c’est la part d’erreur due au fait que n’est qu’un échantillon parmi d’autres.
Mesurer biais et variance par simulation
Section intitulée « Mesurer biais et variance par simulation »Biais et variance se définissent en moyennant sur « tous les échantillons possibles ». Dans la vraie vie, vous n’en avez qu’un. Mais sur une population simulée, dont on connaît , on peut tirer des milliers d’échantillons et tout mesurer. C’est l’expérience la plus instructive de ce cours.
import numpy as npfrom numpy.polynomial import Polynomial
rng = np.random.default_rng(1)
def f_star(x): # salaire moyen de la population (k$) return 70 - 25 * np.exp(-2 * (x - 2))
n, sigma, repetitions = 30, 4.0, 2000grille = np.linspace(2.02, 3.98, 50) # centres de 50 cases de [2, 4], où l'on mesure biais et variance
for degre in [0, 1, 2, 3, 4, 6, 8]: predictions = np.empty((repetitions, grille.size)) for r in range(repetitions): x = rng.uniform(2, 4, n) # un nouvel échantillon de 30 diplômés y = f_star(x) + rng.normal(0, sigma, n) modele = Polynomial.fit(x, y, degre) # moindres carrés dans H = polynômes de degré p predictions[r] = modele(grille) moyenne = predictions.mean(axis=0) # la « machine moyenne » biais2 = np.mean((moyenne - f_star(grille)) ** 2) variance = np.mean(predictions.var(axis=0)) print(f"degré {degre} : biais² {biais2:7.2f} variance {variance:7.2f} " f"erreur attendue {sigma**2 + biais2 + variance:7.2f}")Avec 30 diplômés par échantillon, et 2 000 échantillons, une telle simulation donne des valeurs proches de celles du tableau ci-dessous. Elles varient un peu d’un tirage à l’autre (et d’un générateur aléatoire à l’autre) ; la dernière colonne donne en plus le risque empirique moyen, mesuré sur les données d’apprentissage :
| Degré | Biais² | Variance | Erreur attendue ( + biais² + variance) | Risque empirique moyen |
|---|---|---|---|---|
| 0 | 40,4 | 1,9 | 58,3 | 54,5 |
| 1 | 7,8 | 1,9 | 25,7 | 22,1 |
| 2 | 0,8 | 2,0 | 18,8 | 14,9 |
| 3 | 0,05 | 2,7 | 18,7 | 13,9 |
| 4 | 0,00 | 4,3 | 20,3 | 13,3 |
| 6 | 0,00 | 28,6 | 44,6 | 12,3 |
| 8 | 0,7 | 1 300 | 1 317 | 11,2 |
Lisons ce tableau attentivement, car il contient tout le chapitre.
- Le biais² retrouve l’erreur d’approximation. 40,4 ; 7,8 ; 0,8 ; 0,05 : ce sont, aux fluctuations près, les valeurs 40,45 ; 7,85 ; 0,76 ; 0,044 calculées au chapitre 3.
- La variance explose avec le degré. Modeste jusqu’au degré 3, elle devient énorme au degré 8 : avec 30 points seulement, un polynôme de degré 8 fait des bonds considérables là où les données sont rares, en particulier aux bords de l’intervalle.
- L’erreur attendue a une forme en U, minimale vers les degrés 2 et 3. C’est le bon compromis pour 30 diplômés.
- Le risque empirique, lui, ne fait que baisser (54,5 puis 22,1, 14,9… jusqu’à 11,2), et passe même sous le bruit dès le degré 2. C’est l’optimisme du chapitre 2 en chiffres : si l’on choisissait le degré sur le risque empirique, on prendrait le pire modèle du tableau.
La courbe en U et la capacité
Section intitulée « La courbe en U et la capacité »On résume souvent ce dilemme par un schéma : en abscisse, la capacité du modèle (sa flexibilité : degré du polynôme, profondeur d’un arbre, nombre de paramètres…) ; en ordonnée, les erreurs.
- À gauche, dans la zone de sous-apprentissage (underfitting), le biais domine : le modèle est trop rigide. Il se trompe beaucoup, y compris sur ses données d’apprentissage.
- À droite, dans la zone de surapprentissage (overfitting), la variance domine : le modèle suit le bruit de l’échantillon et généralise mal.
- Le minimum du U est la capacité optimale. Elle dépend de : avec 3 000 diplômés au lieu de 30, la variance de chaque degré serait environ cent fois plus faible, et la capacité optimale se déplacerait vers la droite.
Le diagnostic pratique (comparer le score d’apprentissage et le score sur des données non vues) et le tableau des « boutons de complexité » des modèles classiques sont présentés dans le cours d’Apprentissage automatique. Ici, retenez le mécanisme : chaque bouton déplace le modèle sur l’axe de la capacité.
Accepter un peu de biais : la régularisation
Section intitulée « Accepter un peu de biais : la régularisation »Revenons au MVUE. Viser un biais nul est-il toujours une bonne idée ? Le dilemme dit que non : un estimateur un peu biaisé mais beaucoup moins variable peut avoir une erreur totale plus petite.
C’est exactement l’idée de la régularisation. Au lieu de minimiser le seul risque empirique, on ajoute une pénalité sur la taille des coefficients. Pour la régression ridge :
- le premier terme est la somme des carrés des résidus (le risque empirique, à un facteur près) ;
- le second pénalise les grands coefficients, sauf l’ordonnée à l’origine ;
- règle la force de la pénalité : redonne les moindres carrés, un très grand écrase tous les coefficients vers 0.
En augmentant , on ajoute du biais (les coefficients sont tirés vers 0) et l’on réduit la variance (le polynôme ne peut plus faire de grands bonds). Un polynôme de degré 8 régularisé peut ainsi redevenir raisonnable avec 30 points. La régularisation ne change pas l’espace , elle change la façon d’y choisir : c’est une autre manière de régler la capacité.
En résumé
Section intitulée « En résumé »- Le biais d’un estimateur est l’écart entre sa valeur moyenne et la vraie valeur (négatif : il sous-estime ; positif : il surestime). Sa variance mesure sa dispersion d’un échantillon à l’autre.
- Une machine apprise est un estimateur de : en chaque , on définit son biais et sa variance en moyennant sur les échantillons possibles.
- En régression quadratique : erreur attendue = + biais² + variance. Le bruit est irréductible, le biais² reflète l’erreur d’approximation, la variance l’erreur d’estimation.
- Quand la capacité augmente, le biais baisse et la variance monte : l’erreur de généralisation a une forme en U, et la capacité optimale dépend de la taille de l’échantillon.
- Le risque empirique décroît toujours avec la capacité : il ne permet pas de choisir la capacité.
- La régularisation (ridge, par exemple) accepte un peu de biais pour réduire beaucoup la variance, à l’opposé de la logique du MVUE.
Exercices
Section intitulée « Exercices »Exercice · Lire un biais
facileTrois méthodes estiment le salaire médian d’une promotion, qui vaut réellement 60 k$. En les appliquant à 1 000 échantillons simulés, on obtient :
- méthode A : moyenne des estimations 60,1, écart-type 6 ;
- méthode B : moyenne 57, écart-type 1 ;
- méthode C : moyenne 63, écart-type 4.
Donnez le signe du biais de chaque méthode et calculez (approximativement) son erreur quadratique moyenne. Laquelle préférez-vous ?
Voir la solution
L’erreur quadratique moyenne vaut biais² + variance, avec variance = écart-type².
- A : biais (quasi sans biais), variance , erreur .
- B : biais (elle sous-estime), variance , erreur .
- C : biais (elle surestime), variance , erreur .
La méthode B, pourtant biaisée, a la plus petite erreur quadratique moyenne. Si l’on sait qu’elle sous-estime de 3 environ, on peut même la corriger. La méthode A est sans biais, mais trop instable pour être utile sur un seul échantillon.
En code
vraie_valeur = 60methodes = {"A": (60.1, 6), "B": (57, 1), "C": (63, 4)} # (moyenne, écart-type)
for nom, (moyenne, ecart_type) in methodes.items(): biais = moyenne - vraie_valeur eqm = biais ** 2 + ecart_type ** 2 # erreur quadratique = biais² + variance print(nom, round(biais, 1), round(eqm, 2))# A 0.1 36.01 / B -3 10 / C 3 25 : B a la plus petite erreurvraie_valeur <- 60moyenne <- c(A = 60.1, B = 57, C = 63)ecart_type <- c(A = 6, B = 1, C = 4)
biais <- moyenne - vraie_valeureqm <- biais^2 + ecart_type^2 # erreur quadratique = biais² + variancerbind(biais, eqm) # A : 0.1 36.01 ; B : -3 10 ; C : 3 25Exercice · Rétrécir un estimateur
moyenOn estime une quantité par , sans biais, de variance . On propose l’estimateur .
- Calculez son biais, sa variance et son erreur quadratique moyenne. Est-il meilleur que ?
- Pour quelles valeurs de l’estimateur devient-il moins bon que ?
Voir la solution
- Biais , donc biais² . Variance . Erreur , contre pour : il est meilleur.
- Pour une valeur quelconque de , l’erreur de vaut . Elle dépasse quand , soit , c’est-à-dire . Le rétrécissement vers 0 n’est rentable que si la vraie valeur n’est pas trop loin de 0 : on échange un risque de biais contre un gain de variance, et le pari peut être perdant. D’où l’intérêt de régler l’intensité du rétrécissement sur des données.
En code
import numpy as np
mu, var_moyenne, a = 10, 25, 0.8biais = a * mu - muvariance = a ** 2 * var_moyenneprint(round(biais, 2), round(variance, 2), round(biais ** 2 + variance, 2)) # -2.0 16.0 20.0
# Question 2 : erreur de 0,8 Ȳ en fonction de mu, comparée aux 25 de Ȳeqm = lambda m: (0.2 * m) ** 2 + 16print([round(eqm(m), 2) for m in (14, 15, 16)]) # [23.84, 25.0, 26.24] : seuil |mu| = 15
# Vérification par simulation (Ȳ de loi normale, moyenne mu, variance 25)rng = np.random.default_rng(0)y_barre = rng.normal(mu, 5, 1_000_000)print(round(np.mean((a * y_barre - mu) ** 2), 2)) # 20.01mu <- 10; var_moyenne <- 25; a <- 0.8biais <- a * mu - muvariance <- a^2 * var_moyennec(biais, variance, biais^2 + variance) # -2 16 20 (contre 25 pour Ȳ)
# Question 2 : erreur de 0,8 Ȳ en fonction de mu, comparée aux 25 de Ȳeqm <- function(m) (0.2 * m)^2 + 16eqm(c(14, 15, 16)) # 23.84 25 26.24 : seuil |mu| = 15uniroot(function(m) eqm(m) - 25, c(0, 100))$root # 15
# Vérification par simulation (Ȳ de loi normale, moyenne mu, variance 25)set.seed(0)y_barre <- rnorm(1e6, mu, 5)mean((a * y_barre - mu)^2) # 19.99Exercice · Démontrer la décomposition
difficileEn un point fixé, on suppose , avec , , et indépendant de l’échantillon d’apprentissage (donc de ). On note . Démontrez que
Voir la solution
Écrivons , somme de trois termes : le bruit, un terme constant (moins le biais), et un terme aléatoire de moyenne nulle.
En élevant au carré et en prenant l’espérance, on obtient les trois carrés et trois doubles produits.
- Les carrés donnent , puis , puis .
- Double produit bruit × constante : .
- Double produit bruit × terme aléatoire : par indépendance, .
- Double produit constante × terme aléatoire : , car .
Il reste bien . L’hypothèse d’indépendance entre le nouveau bruit et l’échantillon d’apprentissage est essentielle : c’est elle qui traduit que l’on évalue la machine sur un nouveau diplômé.
En code
import numpy as np
rng = np.random.default_rng(0)f_star = lambda x: 70 - 25 * np.exp(-2 * (x - 2))sigma, n, x0 = 4, 30, 2.2 # point x fixé : GPA 2,2
pred, y_neuf = [], []for _ in range(20_000): # un échantillon D_n par répétition x = rng.uniform(2, 4, n) y = f_star(x) + rng.normal(0, sigma, n) b1, b0 = np.polyfit(x, y, 1) # machine apprise : une droite pred.append(b0 + b1 * x0) y_neuf.append(f_star(x0) + rng.normal(0, sigma)) # nouveau diplômé, bruit indépendantpred, y_neuf = np.array(pred), np.array(y_neuf)
gauche = np.mean((y_neuf - pred) ** 2)biais2 = (pred.mean() - f_star(x0)) ** 2variance = pred.var()print(round(gauche, 2), round(sigma ** 2 + biais2 + variance, 2)) # 27.17 27.15 : égauxprint(round(biais2, 2), round(variance, 2)) # biais² 7.91, variance 3.24set.seed(0)f_star <- function(x) 70 - 25 * exp(-2 * (x - 2))sigma <- 4; n <- 30; x0 <- 2.2 # point x fixé : GPA 2,2
res <- replicate(20000, { # un échantillon D_n par répétition x <- runif(n, 2, 4) y <- f_star(x) + rnorm(n, 0, sigma) b <- coef(lm(y ~ x)) # machine apprise : une droite c(pred = unname(b[1] + b[2] * x0), y_neuf = f_star(x0) + rnorm(1, 0, sigma)) # nouveau diplômé, bruit indépendant})pred <- res["pred", ]; y_neuf <- res["y_neuf", ]
gauche <- mean((y_neuf - pred)^2)biais2 <- (mean(pred) - f_star(x0))^2variance <- mean((pred - mean(pred))^2)c(gauche, sigma^2 + biais2 + variance) # 26.97 27.22 : égaux au bruit prèsc(biais2, variance) # biais² 7.97, variance 3.25