AdaBoost, pour Adaptive Boosting, est le premier algorithme de boosting à succès, proposé par Yoav Freund et Robert Schapire en 1995. Il enchaîne des modèles très simples, souvent des arbres à une seule question, en donnant plus de poids aux exemples mal classés à chaque étape. Il reste une bonne porte d'entrée vers le gradient boosting.
Un élève qui révise en reprenant d'abord les exercices qu'il a ratés, encore et encore, jusqu'à ne plus buter sur les mêmes.
Une souche : un arbre qui ne pose qu'une question, par exemple « plus de 3 appels au support ? ». À peine mieux que le hasard, mais rapide.
Les clients mal classés voient leur poids augmenter, les bien classés leur poids baisser. Le modèle suivant se concentre donc sur les cas difficiles.
Chaque modèle reçoit un poids selon sa précision. La prédiction finale est un vote pondéré de tous les modèles.
Ancienneté, appels au support, montant mensuel, contrat, incidents récents, et le départ observé. L'objectif : cibler une campagne de rétention sur les clients les plus à risque.
Sur le jeu d'exemple, une souche seule atteint une AUC de 0,63 ; 200 souches boostées montent à 0,76. Dans les 10 % de clients les mieux scorés, 59 % partent, contre 22 % en moyenne.
La campagne ne peut appeler qu'une partie de la base. On mesure la part de vrais partants parmi les clients ciblés, comparée au taux moyen : c'est le lift, ici proche de 2,7.
Noms donnés pour R (adabag) et Python (scikit-learn).
Nombre de modèles faibles. Plus il y en a, plus le modèle s'adapte aux données ; au-delà d'un certain point, il surapprend. À régler avec le taux d'apprentissage.
En Python, learning_rate réduit la contribution de chaque modèle : plus petit, il faut plus de modèles, avec souvent un meilleur résultat. En R, coeflearn choisit la formule de pondération ("Freund" pour l'AdaBoost d'origine).
1 par défaut en Python (souche). En R, adabag construit par défaut des arbres rpart profonds : il faut fixer maxdepth = 1 pour obtenir des souches. Des arbres de profondeur 2 ou 3 captent des interactions entre variables, au prix d'un risque de surapprentissage plus élevé.
# Ciblage anti-churn : AdaBoost en R
library(rpart)
library(adabag)
clients <- read.csv("clients_churn.csv")
clients$churn <- factor(clients$churn)
clients$contrat <- factor(clients$contrat)
set.seed(42)
idx <- sample(nrow(clients), round(0.7 * nrow(clients)))
train <- clients[idx, ]
test <- clients[-idx, ]
# 200 souches (arbres à une seule question) entraînées en série ;
# coeflearn = "Freund" : pondération d'origine d'AdaBoost
modele <- boosting(churn ~ anciennete + appels_support + montant + contrat + incidents_3m,
data = train, mfinal = 200, coeflearn = "Freund",
control = rpart.control(maxdepth = 1))
proba <- predict(modele, newdata = test)$prob[, 2]
# Part de partants dans les 10 % de clients les mieux scorés
top <- proba >= quantile(proba, 0.9)
cat("Churn top 10 % :", round(mean(test$churn[top] == "1"), 2), "\n")
cat("Churn moyen :", round(mean(test$churn == "1"), 2), "\n")
print(round(sort(modele$importance, decreasing = TRUE), 1))
# Ciblage anti-churn : AdaBoost en Python
import pandas as pd
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
clients = pd.read_csv("clients_churn.csv")
X = pd.get_dummies(clients[["anciennete", "appels_support", "montant", "contrat", "incidents_3m"]], dtype=float)
y = clients["churn"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
# Brique de base : une souche, un arbre à une seule question
souche = DecisionTreeClassifier(max_depth=1).fit(X_train, y_train)
print("Une souche seule, AUC :", round(roc_auc_score(y_test, souche.predict_proba(X_test)[:, 1]), 3))
# 200 souches en série, chacune repondère les clients mal classés par les précédentes
modele = AdaBoostClassifier(estimator=DecisionTreeClassifier(max_depth=1), n_estimators=200, learning_rate=0.5, random_state=42)
modele.fit(X_train, y_train)
proba = modele.predict_proba(X_test)[:, 1]
print("AdaBoost, AUC :", round(roc_auc_score(y_test, proba), 3))
# Part de partants dans les 10 % de clients les mieux scorés
top = proba >= pd.Series(proba).quantile(0.9)
print("Churn top 10 % :", round(y_test[top].mean(), 2), "| churn moyen :", round(y_test.mean(), 2))
AdaBoost repondère les exemples mal classés à chaque étape. Le gradient boosting ajuste chaque nouveau modèle sur les erreurs résiduelles du précédent, en suivant le gradient d'une fonction de perte. AdaBoost est un cas particulier de gradient boosting avec une perte exponentielle.
Un arbre de décision réduit à une seule question, avec deux feuilles. Seule, elle prédit mal ; c'est justement le modèle faible idéal pour AdaBoost, qui en combine des centaines.
Parce qu'il augmente sans cesse le poids des exemples mal classés. Un client mal étiqueté, que personne ne peut bien classer, finit par peser très lourd et par déformer les modèles suivants. Les versions modernes du boosting sont plus robustes à ce problème.
Corrige les erreurs par descente de gradient sur une fonction de perte au choix. Plus souple, plus performant.
Voir la fiche → le boosting moderneGradient boosting optimisé et régularisé. La référence actuelle sur données tabulaires.
Voir la fiche → l'approche inverseDes modèles indépendants entraînés en parallèle puis moyennés. Réduit la variance plutôt que le biais.
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