Une régression linéaire qui pénalise la somme des valeurs absolues des coefficients. Effet pratique : les variables inutiles reçoivent un coefficient exactement nul et sortent du modèle. On obtient une équation courte, qui ne garde que les leviers qui comptent vraiment.
Un budget de poids limité. Pour garder une variable, il faut qu'elle rapporte plus qu'elle ne coûte. Les variables qui n'apportent presque rien se retrouvent à zéro.
La pénalité compare les coefficients entre eux. Il faut donc que les variables soient exprimées dans des unités comparables.
Le modèle minimise l'erreur au carré plus lambda fois la somme des |coefficients|. Cette forme de pénalité pousse les petits coefficients exactement à zéro.
Au minimum de l'erreur, le modèle garde souvent quelques variables parasites. La règle « 1 écart-type » choisit un modèle plus court, presque aussi précis.
Surface, budget pub local, concurrents, type de zone, et 15 autres indicateurs remontés par les régions. Pour la démonstration, ces 15 indicateurs sont du pur hasard : le Lasso doit les écarter.
Avec la règle 1 écart-type, le modèle garde les 5 vrais leviers (surface, pub, concurrents, deux zones) et un seul indicateur parasite, à coefficient quasi nul. Au minimum de l'erreur, il en gardait 16 sur 20.
On vérifie d'abord que la sélection a un sens métier et reste stable d'un échantillon à l'autre. L'erreur absolue moyenne en k€ sur des magasins jamais vus confirme ensuite que le modèle court prévoit presque aussi bien : environ 56 k€ ici, contre 55 k€ au minimum de l'erreur.
Noms donnés pour R (glmnet) et Python (scikit-learn).
La force de la pénalité. Plus elle est forte, moins il reste de variables. Toujours choisie par validation croisée : cv.glmnet en R, LassoCV en Python.
lambda.min minimise l'erreur de validation croisée mais garde souvent du bruit. lambda.1se prend le modèle le plus court dont l'erreur reste à moins d'un écart-type du minimum. glmnet la fournit ; en Python, il faut la calculer.
Dans glmnet, alpha règle le mélange Ridge / Lasso. La valeur par défaut, 1, donne le Lasso.
glmnet met les variables à l'échelle tout seul et rend les coefficients dans les unités d'origine. En Python, on standardise soi-même puis on divise les coefficients par l'écart-type pour les relire.
# Leviers du CA magasin : Lasso en R
library(glmnet)
magasins <- read.csv("magasins.csv")
X <- model.matrix(ca_k ~ surface_m2 + budget_pub_k + nb_concurrents + zone, data = magasins)[, -1]
# Démonstration : 15 indicateurs candidats sans aucun lien avec le CA
set.seed(42)
bruit <- matrix(rnorm(nrow(X) * 15), ncol = 15)
colnames(bruit) <- sprintf("indicateur_%02d", 1:15)
X <- cbind(X, bruit)
idx <- sample(nrow(X), round(0.7 * nrow(X)))
cv <- cv.glmnet(X[idx, ], magasins$ca_k[idx], alpha = 1, nfolds = 10) # alpha = 1 : Lasso
min_err <- as.matrix(coef(cv, s = "lambda.min"))[-1, 1]
un_se <- as.matrix(coef(cv, s = "lambda.1se"))[-1, 1]
cat("Variables gardées au minimum de l'erreur :", sum(min_err != 0), "sur", ncol(X), "\n")
cat("Variables gardées avec la règle 1 écart-type :\n")
print(round(un_se[un_se != 0], 2))
pred <- predict(cv, newx = X[-idx, ], s = "lambda.1se")
cat("Erreur absolue moyenne sur les magasins test :", round(mean(abs(magasins$ca_k[-idx] - pred)), 1), "k€\n")
# Leviers du CA magasin : Lasso en Python
import numpy as np
import pandas as pd
from sklearn.linear_model import LassoCV, Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
magasins = pd.read_csv("magasins.csv")
X = pd.get_dummies(magasins[["surface_m2", "budget_pub_k", "nb_concurrents", "zone"]], drop_first=True, dtype=float)
# Démonstration : 15 indicateurs candidats sans aucun lien avec le CA
rng = np.random.default_rng(42)
for i in range(1, 16):
X[f"indicateur_{i:02d}"] = rng.normal(size=len(X))
X_train, X_test, y_train, y_test = train_test_split(X, magasins["ca_k"], test_size=0.3, random_state=42)
echelle = StandardScaler().fit(X_train)
cv = LassoCV(cv=10, random_state=42).fit(echelle.transform(X_train), y_train)
# Règle « 1 écart-type » : le modèle le plus simple presque aussi bon que le meilleur
erreur = cv.mse_path_.mean(axis=1)
se = cv.mse_path_.std(axis=1) / np.sqrt(10)
alpha_1se = cv.alphas_[erreur <= erreur.min() + se[erreur.argmin()]].max()
modele = Lasso(alpha=alpha_1se).fit(echelle.transform(X_train), y_train)
coefs = pd.Series(modele.coef_ / echelle.scale_, index=X.columns)
print("Variables gardées au minimum de l'erreur :", (cv.coef_ != 0).sum(), "sur", X.shape[1])
print("Variables gardées avec la règle 1 écart-type :")
print(coefs[coefs != 0].round(2))
print("Erreur absolue moyenne sur les magasins test :", round(np.mean(np.abs(y_test - modele.predict(echelle.transform(X_test)))), 1), "k€")
La pénalité sur la valeur absolue a un « coin » en zéro. Tant que l'apport d'une variable à l'ajustement reste inférieur au coût de la pénalité, la meilleure solution est de laisser son coefficient à zéro. La pénalité au carré de Ridge n'a pas ce coin et rétrécit sans annuler.
Non. Avec des variables corrélées, il peut garder l'une et écarter l'autre presque au hasard, et le choix change d'un échantillon à l'autre. Il faut vérifier la stabilité de la sélection et le sens métier avant de conclure.
lambda.min donne l'erreur de validation croisée la plus basse. lambda.1se donne le modèle le plus simple dont l'erreur reste à moins d'un écart-type de ce minimum. Pour sélectionner des variables, lambda.1se est en général plus fiable.
La pénalité au carré : aucun coefficient à zéro, souvent meilleure quand tout compte un peu.
Voir la fiche → pour les variables corréléesMélange Lasso et Ridge : sélectionne, mais garde ensemble les variables qui se ressemblent.
Voir la fiche → l'étape d'aprèsUne fois les variables choisies, une régression classique sur elles donne des coefficients non rétrécis.
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