XGBoost vs LightGBM en 2026 : Gradient Boosting et Questions d'Entretien Data Science
Maîtrisez XGBoost et LightGBM pour réussir vos entretiens en data science. Comparez les algorithmes de gradient boosting, apprenez l'optimisation des hyperparamètres et préparez-vous aux questions techniques avec des exemples Python.

XGBoost et LightGBM demeurent les implémentations de gradient boosting les plus performantes pour les données tabulaires en 2026, surpassant régulièrement le deep learning sur les datasets structurés. Ces deux bibliothèques ont considérablement évolué, avec XGBoost 2.1 et LightGBM 4.5 qui introduisent des améliorations de l'accélération GPU et une meilleure gestion des variables catégorielles.
Lorsqu'on demande « Pourquoi utiliser XGBoost plutôt qu'un réseau de neurones ? », il convient de souligner que le gradient boosting gère plus efficacement les données tabulaires avec moins d'échantillons, nécessite moins d'ingénierie des features et fournit une importance des variables intégrée. Les réseaux de neurones excellent sur les données non structurées (images, texte, audio) mais peinent avec les features tabulaires hétérogènes.
Différences Fondamentales entre Gradient Boosting et Random Forests
Le gradient boosting et les Random Forests utilisent tous deux des arbres de décision, mais l'approche d'entraînement diffère fondamentalement. Les Random Forests entraînent les arbres indépendamment en parallèle, puis calculent la moyenne des prédictions. Le gradient boosting entraîne les arbres séquentiellement, chaque arbre corrigeant les erreurs de l'ensemble précédent.
La formulation mathématique clarifie cette distinction. À l'itération m, le gradient boosting ajuste un nouvel arbre h_m(x) au gradient négatif de la fonction de perte par rapport aux prédictions de l'ensemble actuel. Pour la perte quadratique, ce gradient négatif correspond aux résidus.
# gradient_boosting_demo.py
import numpy as np
from sklearn.tree import DecisionTreeRegressor
def gradient_boosting_from_scratch(X, y, n_estimators=100, learning_rate=0.1, max_depth=3):
"""Gradient boosting simplifié pour la régression, illustrant l'algorithme."""
# Initialisation des prédictions avec la moyenne (minimise l'erreur quadratique)
predictions = np.full(len(y), y.mean())
trees = []
for _ in range(n_estimators):
# Calcul du gradient négatif (résidus pour la perte MSE)
residuals = y - predictions
# Ajustement d'un arbre aux résidus
tree = DecisionTreeRegressor(max_depth=max_depth)
tree.fit(X, residuals)
trees.append(tree)
# Mise à jour des prédictions avec shrinkage (learning rate)
predictions += learning_rate * tree.predict(X)
return trees, y.mean()Cette dépendance séquentielle rend l'entraînement du gradient boosting plus lent que celui des Random Forests, mais généralement plus précis sur le même dataset.
Architecture XGBoost et Paramètres Clés
XGBoost (eXtreme Gradient Boosting) a introduit plusieurs optimisations rendant le gradient boosting pratique à grande échelle. La bibliothèque utilise une fonction objectif régularisée combinant la perte avec des pénalités L1 et L2 sur les poids des feuilles, réduisant le surapprentissage sans validation croisée extensive.
# xgboost_classification.py
import xgboost as xgb
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
# Génération de données de classification synthétiques
X, y = make_classification(n_samples=10000, n_features=20, n_informative=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# XGBoost avec hyperparamètres couramment optimisés
model = xgb.XGBClassifier(
n_estimators=500, # Nombre d'itérations de boosting
max_depth=6, # Profondeur maximale de l'arbre (contrôle la complexité)
learning_rate=0.1, # Facteur de shrinkage (eta dans la doc XGBoost)
subsample=0.8, # Ratio d'échantillonnage des lignes par arbre
colsample_bytree=0.8, # Ratio d'échantillonnage des colonnes par arbre
reg_alpha=0.1, # Régularisation L1 sur les poids des feuilles
reg_lambda=1.0, # Régularisation L2 sur les poids des feuilles
tree_method='hist', # Algorithme basé sur les histogrammes (plus rapide)
early_stopping_rounds=50, # Arrêt si pas d'amélioration après 50 itérations
random_state=42
)
model.fit(
X_train, y_train,
eval_set=[(X_test, y_test)], # Ensemble de validation pour early stopping
verbose=False
)
print(f"Meilleure itération: {model.best_iteration}")
print(f"Accuracy sur le test: {model.score(X_test, y_test):.4f}")Le paramètre tree_method='hist' mérite une attention particulière. La construction d'arbres basée sur les histogrammes discrétise les features continues en bins, réduisant l'utilisation mémoire et accélérant la recherche des splits. XGBoost 2.0+ utilise cette méthode par défaut.
LightGBM : Croissance Leaf-Wise et Gestion des Catégorielles
LightGBM (Light Gradient Boosting Machine) de Microsoft a introduit deux innovations le rendant souvent plus rapide que XGBoost : la croissance leaf-wise et le Gradient-based One-Side Sampling (GOSS).
Les arbres de décision traditionnels croissent niveau par niveau, divisant tous les nœuds à une profondeur donnée avant d'aller plus en profondeur. LightGBM croît feuille par feuille, divisant toujours la feuille avec le gain potentiel le plus élevé. Cette approche asymétrique produit des arbres plus complexes avec moins de splits, atteignant souvent une perte d'entraînement plus basse plus rapidement.
# lightgbm_with_categorical.py
import lightgbm as lgb
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
# Création d'un dataset avec features catégorielles
np.random.seed(42)
df = pd.DataFrame({
'category_a': np.random.choice(['low', 'medium', 'high'], 10000),
'category_b': np.random.choice(['type1', 'type2', 'type3', 'type4'], 10000),
'numeric_1': np.random.randn(10000),
'numeric_2': np.random.randn(10000),
'target': np.random.randint(0, 2, 10000)
})
# Conversion en dtype catégoriel (LightGBM le détecte automatiquement)
df['category_a'] = df['category_a'].astype('category')
df['category_b'] = df['category_b'].astype('category')
X = df.drop('target', axis=1)
y = df['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# LightGBM gère nativement les features catégorielles
model = lgb.LGBMClassifier(
n_estimators=500,
max_depth=-1, # Pas de limite (la croissance leaf-wise contrôle la complexité)
num_leaves=31, # Nombre maximal de feuilles par arbre (paramètre clé LightGBM)
learning_rate=0.1,
subsample=0.8,
colsample_bytree=0.8,
min_child_samples=20, # Échantillons minimum dans une feuille
reg_alpha=0.1,
reg_lambda=1.0,
random_state=42,
verbose=-1
)
model.fit(
X_train, y_train,
eval_set=[(X_test, y_test)],
callbacks=[lgb.early_stopping(50, verbose=False)]
)
print(f"Meilleure itération: {model.best_iteration_}")
print(f"Accuracy sur le test: {model.score(X_test, y_test):.4f}")La gestion native des variables catégorielles de LightGBM surpasse le one-hot encoding pour les features à haute cardinalité. L'algorithme trouve des splits optimaux parmi les valeurs catégorielles sans créer de matrices creuses.
Prêt à réussir tes entretiens Data Science & ML ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
XGBoost vs LightGBM : Comparaison Pratique
Le choix entre XGBoost et LightGBM dépend des caractéristiques du dataset et des contraintes. Voici une comparaison directe basée sur des benchmarks et l'expérience pratique :
| Aspect | XGBoost 2.1 | LightGBM 4.5 |
|---|---|---|
| Vitesse d'entraînement | Plus lent sur grands datasets | 2-5x plus rapide avec GOSS |
| Utilisation mémoire | Plus élevée | Plus basse (binning histogramme) |
| Features catégorielles | Nécessite encodage | Support natif |
| Croissance des arbres | Level-wise (défaut) | Leaf-wise |
| Support GPU | CUDA, méthode histogramme | CUDA, support natif |
| Risque de surapprentissage | Plus faible (level-wise) | Plus élevé (leaf-wise, ajuster num_leaves) |
| Petits datasets (<10k lignes) | Souvent meilleur | Comparable |
| Grands datasets (>1M lignes) | Plus lent | Préféré |
Pour les tâches de feature engineering où le temps d'entraînement compte, l'avantage de vitesse de LightGBM devient significatif lors d'expérimentations itératives.
Stratégie d'Optimisation des Hyperparamètres pour les Entretiens
Les recruteurs demandent fréquemment comment optimiser les modèles de gradient boosting. Une approche structurée démontre une réflexion systématique plutôt qu'une recherche en grille aléatoire.
# hyperparameter_tuning.py
import optuna
import xgboost as xgb
from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=5000, n_features=20, n_informative=10, random_state=42)
def objective(trial):
"""Fonction objectif Optuna pour l'optimisation des hyperparamètres XGBoost."""
params = {
# Commencer par learning rate et n_estimators
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True),
'n_estimators': trial.suggest_int('n_estimators', 100, 1000),
# Complexité des arbres (le plus important pour le compromis biais-variance)
'max_depth': trial.suggest_int('max_depth', 3, 10),
'min_child_weight': trial.suggest_int('min_child_weight', 1, 10),
# Régularisation (réduire le surapprentissage)
'reg_alpha': trial.suggest_float('reg_alpha', 1e-8, 10.0, log=True),
'reg_lambda': trial.suggest_float('reg_lambda', 1e-8, 10.0, log=True),
# Échantillonnage (gradient boosting stochastique)
'subsample': trial.suggest_float('subsample', 0.5, 1.0),
'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0),
'tree_method': 'hist',
'random_state': 42
}
model = xgb.XGBClassifier(**params)
scores = cross_val_score(model, X, y, cv=5, scoring='roc_auc')
return scores.mean()
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=50, show_progress_bar=True)
print(f"Meilleur ROC-AUC: {study.best_value:.4f}")
print(f"Meilleurs paramètres: {study.best_params}")L'ordre de priorité d'optimisation est important : learning rate et nombre d'estimateurs d'abord, puis complexité des arbres (max_depth, num_leaves), ensuite régularisation, puis ratios d'échantillonnage. Cela reflète l'impact des paramètres sur le compromis biais-variance.
Questions d'Entretien Courantes sur le Gradient Boosting
Les entretiens en data science testent à la fois la compréhension théorique et les compétences pratiques de débogage. Ces questions apparaissent fréquemment dans les entretiens d'entreprises travaillant avec des données tabulaires.
Q : Pourquoi le gradient boosting surapprend-il plus facilement que les Random Forests ?
Le gradient boosting entraîne séquentiellement, chaque arbre ajustant explicitement les erreurs de l'ensemble. Les arbres tardifs peuvent mémoriser le bruit dans les résidus. Les Random Forests entraînent les arbres indépendamment sur des échantillons bootstrap, et le moyennage réduit la variance. La régularisation (learning rate, subsampling, contraintes sur les arbres) atténue cela dans le gradient boosting.
Q : Qu'est-ce qui cause des résultats différents de XGBoost sur les mêmes données ?
Le non-déterminisme provient de trois sources : l'échantillonnage des lignes (subsample), l'échantillonnage des colonnes (colsample_bytree) et la construction parallèle des histogrammes. Définir random_state fixe les deux premiers. Pour une reproductibilité exacte, définir également n_jobs=1, bien que cela ralentisse l'entraînement.
Q : Comment gérer le déséquilibre des classes dans XGBoost ?
Trois approches fonctionnent :
scale_pos_weight: Définir à(nombre_négatifs / nombre_positifs)pour la classification binairesample_weight: Passer des poids d'instances àfit()- Rééchantillonnage : SMOTE ou sous-échantillonnage aléatoire avant l'entraînement
L'approche scale_pos_weight modifie la fonction de perte et préserve la distribution originale des données, souvent préférée au rééchantillonnage.
Q : Quand choisir CatBoost plutôt que XGBoost ou LightGBM ?
CatBoost excelle lorsque le dataset contient de nombreuses features catégorielles à haute cardinalité, et lorsque réduire le surapprentissage avec un tuning minimal est une priorité. Son boosting ordonné et sa structure d'arbre symétrique le rendent plus résistant au surapprentissage sur les petits datasets. Le compromis est un entraînement plus lent que LightGBM.
Pour approfondir les fondamentaux de la classification, consulter le module de classification supervisée.
Importance des Features et Interprétabilité du Modèle
Expliquer les prédictions est essentiel dans les industries réglementées et renforce la confiance des parties prenantes. XGBoost et LightGBM fournissent tous deux une importance des features intégrée, mais l'interprétation nécessite de la prudence.
# feature_importance.py
import xgboost as xgb
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=5000, n_features=20, n_informative=10, random_state=42)
feature_names = [f'feature_{i}' for i in range(20)]
model = xgb.XGBClassifier(n_estimators=100, random_state=42)
model.fit(X, y)
# Trois types d'importance disponibles
importance_types = ['weight', 'gain', 'cover']
for imp_type in importance_types:
importance = model.get_booster().get_score(importance_type=imp_type)
print(f"\nImportance {imp_type.upper()} (top 5):")
sorted_imp = sorted(importance.items(), key=lambda x: x[1], reverse=True)[:5]
for feat, score in sorted_imp:
print(f" {feat}: {score:.2f}")- Weight : Nombre de fois qu'une feature apparaît dans les splits à travers tous les arbres
- Gain : Amélioration moyenne de la fonction objectif lorsque la feature est utilisée pour le split
- Cover : Nombre moyen d'échantillons affectés par les splits sur cette feature
Le gain fournit généralement la mesure d'importance la plus significative, car elle est directement liée à l'amélioration du modèle. Cependant, les features corrélées peuvent avoir une importance sous-estimée puisque le modèle peut splitter sur l'une ou l'autre.
Pour une interprétation causale, les valeurs SHAP (disponibles via la bibliothèque shap) fournissent des attributions de features cohérentes et théoriquement fondées par prédiction.
Considérations pour le Déploiement en Production
Le déploiement de modèles de gradient boosting introduit des préoccupations de latence et de sérialisation différentes de l'entraînement.
# model_serialization.py
import xgboost as xgb
import json
# Entraînement d'un modèle
model = xgb.XGBClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# Sauvegarde au format binaire natif XGBoost (recommandé pour la production)
model.save_model('model.ubj') # Format Universal Binary JSON
# Chargement pour l'inférence
loaded_model = xgb.XGBClassifier()
loaded_model.load_model('model.ubj')
# Pour le versioning du modèle, sauvegarder avec les métadonnées
metadata = {
'version': '1.0.0',
'trained_at': '2026-09-17',
'features': feature_names,
'best_iteration': model.best_iteration
}
with open('model_metadata.json', 'w') as f:
json.dump(metadata, f)La latence d'inférence dépend de la profondeur et du nombre d'arbres. Pour les applications temps réel avec des exigences strictes de latence (moins de 10ms), considérer :
- Réduire
n_estimatorsavec un learning rate plus élevé - Limiter
max_depthà 4-5 - Utiliser la méthode
predict()aveciteration_rangepour utiliser moins d'arbres
Points Clés pour les Entretiens XGBoost et LightGBM
- Le gradient boosting entraîne les arbres séquentiellement sur les résidus, contrairement aux Random Forests qui entraînent en parallèle et moyennent
- XGBoost ajoute une régularisation L1/L2 à la fonction objectif, réduisant le surapprentissage sans validation croisée extensive
- LightGBM utilise la croissance leaf-wise et l'échantillonnage GOSS, le rendant 2-5x plus rapide sur les grands datasets
- La gestion native des catégorielles dans LightGBM surpasse le one-hot encoding pour les features à haute cardinalité
- Optimiser dans l'ordre : learning rate, complexité des arbres, régularisation, ratios d'échantillonnage
scale_pos_weightgère le déséquilibre des classes en modifiant la fonction de perte, préservant la distribution originale- L'importance basée sur le gain mesure l'amélioration réelle du modèle, mais les features corrélées peuvent sembler moins importantes
- Pour la production, utiliser le format
.ubjet considérer la réduction du nombre d'arbres pour les applications sensibles à la latence
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
Tu saurais repérer le bug en Data Science & ML ?
Un vrai bout de code, un bug caché, une tentative par jour. Sans compte pour essayer.

Écrit par
Anthony Fillion-MailletFondateur de SharpSkill
Développeur fullstack depuis plus de 10 ans. Il dirige SharpSkill et répond de tout ce qui y est publié.
Mis à jour le 17 septembre 2026
Tags
Partager
Articles similaires

MLOps en 2026 : MLflow, Model Registry et questions d'entretien technique
Questions d'entretien MLOps couvrant le cycle de vie ML, le suivi des expérimentations MLflow, la promotion via le model registry, les patterns de déploiement, la supervision de dérive et le system design pour 2026, avec du code Python et des réponses.

PyTorch vs TensorFlow en 2026 : quel framework de deep learning choisir ?
Comparaison complète entre PyTorch et TensorFlow en 2026 : performances, déploiement, écosystème et expérience développeur pour orienter le choix du bon framework.

Algorithmes de Machine Learning : Guide Complet pour les Entretiens Techniques
Guide complet des algorithmes de machine learning pour les entretiens techniques. Couvre les modeles lineaires, arbres de decision, methodes d ensemble, clustering, metriques d evaluation et regularisation avec scikit-learn.