LightGBM vs XGBoost : comparaison des performances et cas d'utilisation

Dans le domaine pratique de la science des données et de l'apprentissage automatique, les arbres de décision à gradient boosting (GBDT) sont sans conteste l'arme absolue pour la modélisation de données structurées. Dans cet écosystème, XGBoost a longtemps occupé la place de leader, grâce à ses performances remarquables et à son large soutien communautaire, devenant le choix privilégié d'innombrables compétitions de data science et projets industriels. Cependant, LightGBM, proposé par Microsoft Research, a lancé un défi de taille à ce maître, en mettant en avant sa légèreté et son efficacité. Pour les décideurs techniques et les data scientists, face à ces deux frameworks de premier plan, le choix ne se résume plus à « lequel est le meilleur », mais à « dans quelles situations l'un est plus adapté que l'autre ».

Cet article analyse en profondeur les différences fondamentales entre LightGBM et XGBoost, sans se limiter à une comparaison superficielle des vitesses. Il explore également les principes algorithmiques, la gestion de la mémoire et l'adaptabilité aux données. À travers des mesures de performance réelles, des exemples de code et le comportement sur différents jeux de données, nous dresserons une carte claire pour guider votre choix. Que vous traitiez des données creuses de haute dimension à l'échelle de diazines de millions de lignes, ou que vous recherchiez la vitesse d'itération la plus rapide avec des ressources de calcul limitées, comprendre les mécanismes internes de ces deux outils vous permettra de prendre de meilleures décisions dès le début du projet et d'éviter de perdre du temps dans les profondeurs du réglage des hyperparamètres.

1. Principes fondamentaux : du « pré-tri » à l'histogramme, un changement de paradigme

Pour comprendre leurs différences de performence, il faut revenir à la manière la plus fondamentale dont chacun construit ses arbres de décision. C'est comme comparer deux méthodes de construction : l'une, finement ouvragée mais aux étapes fastidieuses ; l'autre, préfabriquée et modulaire, d'une efficacité surprenante.

XGBoost utilise un algorithme appelé pre-sorted (pré-tri). Pour trouver le meilleur point de division de chaque caractéristique, il doit d'abord trier toutes les valeurs de cette caractéristique pour l'ensemble des échantillons et conserver le résultat du tri. Ensuite, à chaque recherche de point de division, l'algorithme parcourt séquentiellement toutes les positions de division possibles et calcule le gain.

# Logique simplifiée de la recherche du point de division pour XGBoost (conceptuel)
for colonne in toutes_les_colonnes:
    valeurs_triees = trier_au_préalable(donnees[colonne])  # étape de pré-tri
    for seuil in valeurs_triees:
        gain = calculer_gain_de_division(sous_ensemble_gauche, sous_ensemble_droit)  # calcul itératif
        mettre_a_jour_meilleure_division(gain, seuil)

Cette méthode est très précise et garantit de trouver le point de division théoriquement optimal, mais son coût est élevé :

  • Consommation d'espace : il faut stocker les valeurs de caractéristiques et leurs indices triés, ce qui occupe environ le double de la mémoire des données brutes.
  • Coût temporel : le parcours de chaque caractéristique et de chaque point de division possible pour effectuer les calculs entraîne une complexité élevée, surtout lorsque la caractéristique prend de nombreuses valeurs.

LightGBM introduit quant à lui l'algorithme d'histogramme, une stratégie approximative mais efficace. Il ne traite plus directement les valeurs continues à virgule flottante : il discrétise d'abord les valeurs continues de chaque caractéristique en un nombre fini de compartiments entiers (par exemple 256), formant ainsi un histogramme. Toutes les informations statistiques (comme les gradients ou le nombre d'échantillons) sont accumulées dans ces compartiments.

# Logique simplifiée de l'algorithme d'histogramme pour LightGBM (conceptuel)
for attribut in toutes_les_colonnes:
    histogramme = construire_histogramme(donnees[attribut], nb_bins=256)  # construction de l'histogramme
    for indice_bin in range(256):  # parcours des 256 compartiments, et non de toutes les valeurs
        gain = calculer_gain_depuis_histogramme(histogramme, indice_bin)
        mettre_a_jour_meilleure_division(gain, indice_bin)

Ce changement apporte des avantages fondamentaux :

  • Réduction importante de la mémoire : il suffit de stocker les indices de compartiments discrets et les statistiques d'histogramme, ce qui diminue nettement la consommation mémoire.
  • Gain spectaculaire en efficacité de calcul : la complexité de la recherche du point de division passe de O(#data * #feature) à O(#bins * #feature). Lorsque le volume de données est énorme, on passe du parcours de milliards de valeurs d'échantillons au parcours d'un nombre fixe de quelques centaines de compartiments, ce qui se traduit par une accélération exponentielle.
  • Parallélisation et optimisations de cache naturelles : les opérations sur des compartiments entiers se prêtent plus facilement à l'optimisation du cache et au calcul parallèle.

Remarque : l'algorithme d'histogramme est une compression avec perte, qui échange de la précision contre de l'efficacité. Toutefois, dans la plupart des cas réels, cette légère perte de précision est largement compensée par l'énorme gain de vitesse. Elle peut même permettre davantage d'itérations ou un réglage plus fin des hyperparamètres, aboutissant parfois à de meilleurs résultats finaux.

2. Stratégie de croissance : divergence entre « croissance par niveau » et « croissance par feuille »

La manière dont l'arbre de décision croît constitue une autre différence philosophique majeure. Elle détermine si le modèle s'étend de façon équilibrée mais prudente, ou s'il s'enfonce de façon gourmande mais efficace.

XGBoost adopte une stratégie Level-wise (croissance par niveau). C'est comme une école stricte où tous les élèves d'un même niveau (les nœuds feuilles) doivent obtenir leur diplôme (se diviser) en même temps, qu'ils soient brillants ou en difficulté. L'avantage de cette stratégie est que la complexité du modèle est facile à contrôler, le sur-apprentissage est moins probable, et elle se prête très bien au calcul parallèle, car les divisions d'un même niveau peuvent être effectuées simultanément.

LightGBM adopte une stratégie Leaf-wise (croissance par feuile). Elle ressemble davantage à un mentor qui adapte son enseignement : à chaque étape, parmi toutes les feuilles actuelles, elle choisit celle qui offre le « meilleur gain après division » (c'est-à-dire le gain de gradient le plus élevé) pour la diviser. Cette stratégie est une optimisation plus gourmande qui, à nombre de divisions égal, réduit plus efficacement la fonction de perte et permet donc d'obtenir une meilleure précision.

Pour comparer plus concrètement, observons le schéma du processus de croissance ci-dessous.

Étiquettes: lightgbm XGBoost GBDT Histogram Leaf-wise

Publié le 16 septembre à 17h44