Une régression qui combine les deux pénalités : celle du Lasso, qui met des variables à zéro, et celle de Ridge, qui stabilise. Quand les variables vont par groupes très corrélés, le Lasso en garde une au hasard ; Elastic Net garde le groupe ensemble tout en écartant ce qui est inutile.
Un recruteur qui doit réduire l'équipe. Le Lasso garde un seul des trois jumeaux et renvoie les deux autres. Elastic Net garde les trois jumeaux avec un rôle réduit, et renvoie les vrais inutiles.
L'erreur est pénalisée à la fois par la somme des |coefficients| (Lasso) et par la somme des coefficients au carré (Ridge).
Un paramètre de mélange va de 0 (Ridge pur) à 1 (Lasso pur). À 0,5, le modèle sélectionne tout en partageant le poids entre variables corrélées.
Pour un mélange donné, la force de la pénalité se choisit par validation croisée, comme pour Ridge ou Lasso.
Des chiffres manuscrits scannés, comme sur un formulaire ou un bon de livraison. Chaque image donne 64 variables, et deux pixels voisins sont très corrélés. Le modèle doit reconnaître le chiffre de 0 à 9.
Sur le jeu d'exemple, à pénalité égale, le Lasso n'utilise que 33 pixels et reconnaît 88 % des chiffres. Elastic Net en utilise 44 pour 92 %, Ridge 60 pour 93,5 %. Elastic Net garde l'essentiel de la précision avec environ un quart de pixels en moins.
Les dix chiffres sont à peu près équilibrés : l'exactitude (part d'images bien lues) est ici une bonne mesure. On la lit à côté du nombre de pixels utilisés, qui dit combien le modèle est simple.
Noms donnés pour R (glmnet) et Python (scikit-learn). Les noms se croisent : lisez bien.
Le mélange. 1 = Lasso, 0 = Ridge. 0,5 est un bon départ ; on peut aussi tester 0,2, 0,5 et 0,8 en validation croisée. En R c'est alpha, en Python l1_ratio.
La force de la pénalité. En R, lambda, choisi par cv.glmnet. En Python, alpha pour ElasticNet (régression) ou C, son inverse, pour LogisticRegression : plus C est petit, plus la pénalité est forte.
En classification avec scikit-learn, seul le solveur saga accepte le mélange des deux pénalités. Il converge mieux sur des variables mises à l'échelle.
# Lecture de chiffres manuscrits : Elastic Net en R
library(glmnet)
chiffres <- read.csv("chiffres_manuscrits.csv")
X <- as.matrix(chiffres[, 1:64]) / 16 # 64 pixels, voisins très corrélés
y <- factor(chiffres$chiffre)
set.seed(42)
idx <- sample(nrow(X), round(0.7 * nrow(X)))
# alpha : 1 = Lasso, 0 = Ridge, entre les deux = Elastic Net
for (a in c(1, 0.5, 0)) {
cv <- cv.glmnet(X[idx, ], y[idx], family = "multinomial", alpha = a, nfolds = 5)
pred <- predict(cv, newx = X[-idx, ], s = "lambda.1se", type = "class")
# Un pixel est utilisé s'il a un coefficient non nul pour au moins un chiffre
poids <- sapply(coef(cv, s = "lambda.1se"), function(m) abs(as.matrix(m)[-1, 1]))
cat("alpha", a, ": exactitude", round(mean(pred[, 1] == y[-idx]), 3),
"| pixels utilisés", sum(rowSums(poids) > 0), "sur 64\n")
}
# Lecture de chiffres manuscrits : Elastic Net en Python
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
chiffres = pd.read_csv("chiffres_manuscrits.csv")
X = chiffres.drop(columns="chiffre") / 16 # 64 pixels, voisins très corrélés
y = chiffres["chiffre"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# l1_ratio : 1 = Lasso, 0 = Ridge, entre les deux = Elastic Net
# (scikit-learn >= 1.8 ; avant, ajouter penalty="elasticnet")
for l1_ratio in [1.0, 0.5, 0.0]:
modele = LogisticRegression(l1_ratio=l1_ratio, C=0.1, solver="saga", max_iter=5000)
modele.fit(X_train, y_train)
pixels = (np.abs(modele.coef_).sum(axis=0) > 0).sum()
print("l1_ratio", l1_ratio, ": exactitude", round(modele.score(X_test, y_test), 3), "| pixels utilisés", pixels, "sur 64")
Quand les variables sont corrélées par groupes. Le Lasso garde alors une variable du groupe presque au hasard, et ce choix change d'un échantillon à l'autre. Elastic Net répartit le poids sur le groupe et donne une sélection plus stable.
On teste quelques valeurs, par exemple 0,2, 0,5 et 0,8, et pour chacune on choisit la force de la pénalité par validation croisée. On garde le couple qui donne la meilleure erreur, ou le modèle plus simple si l'écart est faible.
Oui. La double pénalité s'applique à une régression logistique : glmnet avec family = "binomial" ou "multinomial" en R, LogisticRegression avec le solveur saga en Python.
Plus radical : modèle plus court, mais instable quand les variables sont corrélées.
Voir la fiche → la stabilité pureGarde toutes les variables avec des poids réduits. Souvent un peu plus précis, jamais sélectif.
Voir la fiche → le modèle de baseElastic Net en classification, c'est une régression logistique avec la double pénalité.
Voir la fiche →Dataistudio forme les équipes au machine learning et à l'IA, sur des cas concrets.
Nous utilisons des cookies de mesure d'audience et de suivi publicitaire pour comprendre la fréquentation du site et l'efficacité de nos annonces. Rien n'est déposé sans votre accord. En savoir plus