# 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. - Published: 2026-09-17 - Updated: 2026-09-17 - Author: Anthony Fillion-Maillet - Tags: xgboost, lightgbm, gradient-boosting, machine-learning, data-science-interview - Reading time: 9 min --- 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. > **Conseil pour l'Entretien** > > 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. ```python # 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](https://xgboost.readthedocs.io/en/stable/) (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. ```python # 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](https://lightgbm.readthedocs.io/en/stable/) (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. ```python # 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. ## 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](/blog/data-science/feature-engineering-machine-learning-techniques-interview-2026) 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. ```python # 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 : 1. `scale_pos_weight` : Définir à `(nombre_négatifs / nombre_positifs)` pour la classification binaire 2. `sample_weight` : Passer des poids d'instances à `fit()` 3. 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](https://catboost.ai/en/docs/) 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](/technologies/data-science/interview-questions/ml-supervised-classification). ## 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. ```python # 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](https://shap.readthedocs.io/en/latest/)) 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. ```python # 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_estimators` avec un learning rate plus élevé - Limiter `max_depth` à 4-5 - Utiliser la méthode `predict()` avec `iteration_range` pour 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_weight` gè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 `.ubj` et considérer la réduction du nombre d'arbres pour les applications sensibles à la latence --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/fr/blog/data-science/xgboost-lightgbm-gradient-boosting-interview-2026