Des centaines de petits arbres de décision ajoutés l'un après l'autre, chacun chargé de corriger l'erreur laissée par les précédents. C'est le principe derrière XGBoost, LightGBM et CatBoost, et la méthode qui gagne le plus souvent sur les données en tableau.
Un tireur vise une cible, puis un deuxième tire en corrigeant l'écart du premier, un troisième corrige ce qui reste. Au bout de 300 tirs correctifs, on est très près du centre.
Le modèle commence par une valeur unique pour tout le monde : la fréquence moyenne de sinistres, par exemple. L'écart entre cette prévision et la réalité est l'erreur à corriger.
À chaque tour, un arbre de quelques feuilles cherche où la prévision se trompe le plus : les jeunes conducteurs, les grosses cylindrées. Techniquement, il suit le gradient de la perte, d'où le nom.
La correction est multipliée par un petit pas d'apprentissage (0,05 par exemple) avant d'être ajoutée. On répète des centaines de fois et on s'arrête quand l'erreur sur des données de validation ne baisse plus.
Âge du conducteur, puissance du véhicule, zone d'habitation, coefficient bonus-malus, durée d'exposition dans l'année. Et la colonne à prédire : le nombre de sinistres déclarés.
Le modèle prédit un nombre de sinistres par année d'assurance, avec une perte de Poisson adaptée aux comptages. Sur le jeu d'exemple, il retrouve seul l'essentiel de la sur-sinistralité des moins de 25 ans, que le GLM à effet d'âge linéaire sous-estime de moitié.
La déviance de Poisson compare les prévisions aux sinistres réels. Ici, elle n'est qu'à peine meilleure que celle du GLM : le gain se voit surtout sur les segments mal captés, d'où le tableau observé / prédit par tranche d'âge.
Ils fonctionnent ensemble : un pas plus petit demande plus d'arbres. Noms donnés pour R (gbm) et Python (scikit-learn).
Le pas d'apprentissage. 0,1 par défaut ; en le descendant vers 0,01, le modèle gagne souvent en précision mais demande plus d'arbres. C'est le premier réglage à fixer.
Le nombre d'arbres. Trop d'arbres mène au surapprentissage. On le choisit par validation croisée (gbm.perf en R) ou par arrêt précoce (early_stopping en Python).
La taille de chaque arbre. De petits arbres (2 à 8 feuilles) suffisent en général. Des arbres plus grands captent des interactions plus complexes et surapprennent plus vite.
La fonction de perte, à choisir selon la cible : bernoulli ou log_loss pour oui / non, poisson pour un comptage, gaussian ou squared_error pour un montant. En Python, la perte Poisson est disponible dans HistGradientBoostingRegressor.
# Fréquence de sinistres auto : Gradient Boosting en R
library(gbm)
contrats <- read.csv("sinistres.csv")
contrats$zone <- factor(contrats$zone)
set.seed(42)
idx <- sample(nrow(contrats), round(0.7 * nrow(contrats)))
train <- contrats[idx, ]
test <- contrats[-idx, ]
# offset(log(exposition)) : un contrat vu 6 mois compte pour une demi-année
modele <- gbm(nb_sinistres ~ offset(log(exposition)) + age_conducteur + puissance_cv + zone + bonus_malus,
data = train, distribution = "poisson", n.trees = 1000, interaction.depth = 2,
shrinkage = 0.01, n.minobsinnode = 50, bag.fraction = 0.8, cv.folds = 5)
# Nombre d'arbres retenu par validation croisée
n_opt <- gbm.perf(modele, method = "cv", plot.it = FALSE)
cat("Arbres retenus :", n_opt, "\n")
# predict() ignore l'offset : il renvoie une fréquence par année d'assurance
test$freq <- predict(modele, test, n.trees = n_opt, type = "response")
tranche <- cut(test$age_conducteur, c(17, 24, 45, 65, 85))
observee <- tapply(test$nb_sinistres, tranche, sum) / tapply(test$exposition, tranche, sum)
predite <- tapply(test$freq * test$exposition, tranche, sum) / tapply(test$exposition, tranche, sum)
print(round(cbind(observee, predite), 3))
print(summary(modele, n.trees = n_opt, plotit = FALSE))
# Fréquence de sinistres auto : Gradient Boosting en Python
import pandas as pd
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.linear_model import PoissonRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_poisson_deviance
contrats = pd.read_csv("sinistres.csv")
X = pd.get_dummies(contrats[["age_conducteur", "puissance_cv", "zone", "bonus_malus"]], dtype=int)
# Cible : sinistres par année d'assurance, pondérée par l'exposition
y = contrats["nb_sinistres"] / contrats["exposition"]
w = contrats["exposition"]
X_train, X_test, y_train, y_test, w_train, w_test = train_test_split(X, y, w, test_size=0.3, random_state=42)
# 300 petits arbres (4 feuilles), chacun corrige 5 % de l'erreur restante
modele = HistGradientBoostingRegressor(loss="poisson", max_iter=300, learning_rate=0.05,
max_leaf_nodes=4, min_samples_leaf=50, random_state=42)
modele.fit(X_train, y_train, sample_weight=w_train)
glm = PoissonRegressor(alpha=0, max_iter=1000).fit(X_train, y_train, sample_weight=w_train)
# Déviance de Poisson sur les contrats jamais vus (plus bas = mieux)
print("Déviance GLM :", round(mean_poisson_deviance(y_test, glm.predict(X_test), sample_weight=w_test), 4))
print("Déviance boosting :", round(mean_poisson_deviance(y_test, modele.predict(X_test), sample_weight=w_test), 4))
# Fréquence annuelle observée et prédite par tranche d'âge
test = pd.DataFrame({"tranche": pd.cut(X_test["age_conducteur"], [17, 24, 45, 65, 85]), "expo": w_test,
"obs": y_test * w_test, "boost": modele.predict(X_test) * w_test, "glm": glm.predict(X_test) * w_test})
somme = test.groupby("tranche", observed=True)[["expo", "obs", "boost", "glm"]].sum()
print(somme[["obs", "boost", "glm"]].div(somme["expo"], axis=0).round(3))
La Random Forest entraîne des arbres profonds indépendamment et fait la moyenne de leurs votes. Le Gradient Boosting entraîne de petits arbres l'un après l'autre, chacun corrigeant l'erreur des précédents. Le boosting est souvent plus précis, mais plus sensible aux réglages et au surapprentissage.
XGBoost est une implémentation du Gradient Boosting. Elle ajoute une régularisation des feuilles, une gestion native des valeurs manquantes et un calcul parallélisé à l'intérieur de chaque arbre. LightGBM et CatBoost sont d'autres implémentations du même principe.
Oui, si on ajoute trop d'arbres ou des arbres trop profonds : l'erreur d'apprentissage continue de baisser alors que l'erreur sur de nouvelles données remonte. On s'en protège avec un petit pas d'apprentissage, un tirage partiel des lignes à chaque arbre et un arrêt fixé par validation croisée.
Même principe, avec régularisation, gestion des manquants et calcul parallèle. Le choix par défaut en production.
Voir la fiche → plus simple à réglerDes arbres indépendants qui votent. Un peu moins précis, mais solide dès les réglages par défaut.
Voir la fiche → la référence actuarielleUn GLM qui prédit un nombre d'événements. Moins précis, mais chaque coefficient se lit et se justifie.
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