CatBoost : Guide complet — Categorical Boosting
Résumé — CatBoost (Categorical Boosting) est un algorithme de gradient boosting développé par Yandex (l’équipe de recherche russe derrière le moteur de recherche Yandex) en 2017. Sa particularité est de gérer nativement les features catégorielles sans prétraitement (one-hot encoding, label encoding), grâce à un encodage statistique ordonné qui évite le target leakage. Couplé à son ordered boosting (variante du gradient boosting qui réduit le surapprentissage), CatBoost offre des performances compétitives avec un minimum de tuning.
Principe mathématique
1. Encodage des catégories par statistiques cibles
Plutôt que de convertir les catégories en one-hot encoding (qui explose la dimensionnalité pour les features avec beaucoup de modalités), CatBoost les encode par une statistique ciblée :
$$\text{Encodage}(c) = \frac{\sum_{i=1}^{n} I(x_i = c) \cdot y_i + a \cdot P}{\sum_{i=1}^{n} I(x_i = c) + a}$$
où I(x_i = c) est 1 si l’exemple i a la catégorie c, y_i est la cible, a est un paramètre de lissage (prior), et P est la valeur a priori.
2. Ordered Target Statistics : éviter le target leakage
Le problème classique du target mean encoding est le target leakage : si on calcule la moyenne de la cible pour une catégorie en incluant l’exemple lui-même, le modèle voit indirectement la réponse pendant l’entraînement, provoquant un surapprentissage massif.
CatBoost résout ce problème avec l’Ordered Target Statistics : pour encoder la catégorie de l’exemple i, on ne regarde que les exemples qui le précèdent dans un ordre aléatoire (une permutation σ des données) :
$$\text{Encodage}{ordered}(c_i) = \frac{\sum$$}^{i-1} I(x_{\sigma(j)} = c) \cdot y_{\sigma(j)} + a \cdot P}{\sum_{j=1}^{i-1} I(x_{\sigma(j)} = c) + a
C’est une fenêtre glissante qui garantit que chaque exemple ne voit que le passé (les exemples qui le précèdent dans l’ordre σ). C’est l’analogue d’une série temporelle où les données futures sont inaccessibles.
3. Ordered Boosting
CatBoost va encore plus loin : il applique le même principe d’ordre non seulement au target encoding mais aussi au calcul des gradients (le boosting lui-même). Au lieu de calculer les gradients sur tous les exemples, chaque arbre est entraîné en utilisant les gradients calculés uniquement sur les exemples précédents dans l’ordre σ.
Cette approche ordered boosting réduit considérablement le surapprentissage qui affecte les algorithmes de gradient boosting classiques, surtout sur des petits datasets.
4. Traitement des catégories par combinaisons
Pour capturer les interactions entre features catégorielles, CatBoost construit automatiquement des combinaisons :
- Au niveau du split d’un arbre, CatBoost considère non seulement chaque feature catégorielle individuellement, mais aussi des combinaisons de 2, 3, voire 4 features catégorielles.
- C’est efficace car le nombre de combinaisons reste limité grâce au filtrage par les splits précédents.
Intuition
Imaginez que vous êtes libraire et que vous voulez recommander des livres à vos clients.
L’approche classique (one-hot encoding) : chaque client reçoit un numéro d’identification unique, et vous créez une colonne par client dans votre tableau. Avec 10 000 clients, votre tableau a 10 000 colonnes. C’est ingérable.
L’approche de CatBoost : au lieu de numéroter les clients, vous apprenez directement quel type de livre chaque client aime en regardant l’historique des achats précédents. Vous connaissez vos clients par leur nom, pas par leur numéro — et vous utilisez le passé pour prédire le futur.
L’ordered boosting, c’est comme lire un livre dans l’ordre : vous ne connaissez pas la fin quand vous êtes au chapitre 3. De même, CatBoost ne regarde jamais le futur quand il encode une catégorie.
Implémentation Python
Exemple 1 : CatBoostClassifier basique
import pandas as pd
from catboost import CatBoostClassifier, Pool
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# Données avec features catégorielles
df = pd.DataFrame({
'age': [25, 30, 35, 45, 50, 22, 28, 38, 42, 55],
'revenu': [30000, 45000, 60000, 80000, 95000, 25000, 38000, 70000, 75000, 100000],
'ville': ['Paris', 'Lyon', 'Marseille', 'Paris', 'Bordeaux', 'Lyon', 'Paris', 'Toulouse', 'Marseille', 'Paris'],
'education': ['Licence', 'Master', 'Doctorat', 'Master', 'Licence', 'Bac', 'Licence', 'Master', 'Doctorat', 'Bac'],
'achat': [0, 1, 1, 1, 1, 0, 0, 1, 1, 0]
})
X = df.drop('achat', axis=1)
y = df['achat']
# Identification des colonnes catégorielles
cat_cols = ['ville', 'education']
cat_idx = [X.columns.get_loc(c) for c in cat_cols]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# CatBoost
model = CatBoostClassifier(
iterations=100,
learning_rate=0.1,
depth=6,
loss_function='Logloss',
cat_features=cat_idx,
verbose=False,
random_state=42
)
model.fit(X_train, y_train)
pred = model.predict(X_test)
print(f"Accuracy : {accuracy_score(y_test, pred):.3f}")
Exemple 2 : Comparaison CatBoost vs XGBoost avec encodage
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
import time
# Préparer les données pour XGBoost (encoding nécessaire)
from sklearn.datasets import fetch_openml
X_full, y_full = fetch_openml('adult', version=2, return_X_y=True, as_frame=True)
X_full = X_full.select_dtypes(include=['number', 'category'])
y_full = (y_full == '>50K').astype(int)
X_train, X_test, y_train, y_test = train_test_split(X_full, y_full, test_size=0.2, random_state=42)
# CatBoost (avec catégorielles natives)
cat_full_idx = X_train.select_dtypes(include=['category']).columns.tolist()
start = time.time()
cb = CatBoostClassifier(iterations=200, learning_rate=0.1, depth=6,
cat_features=cat_full_idx, verbose=False, random_state=42)
cb.fit(X_train, y_train)
cb_time = time.time() - start
cb_acc = accuracy_score(y_test, cb.predict(X_test))
print(f"CatBoost : {cb_time:.2f}s | Acc: {cb_acc:.3f}")
Exemple 3 : Feature importance et visualisation
import matplotlib.pyplot as plt
# Feature importance
importances = model.get_feature_importance()
feature_names = X_train.columns
plt.figure(figsize=(8, 5))
plt.barh(range(len(importances)), importances)
plt.yticks(range(len(importances)), feature_names)
plt.xlabel('Importance')
plt.title("CatBoost - Feature Importance")
plt.tight_layout()
plt.savefig('catboost_importance.png', dpi=150)
Exemple 4 : CatBoost avec Pool et early stopping
# API Pool pour optimisation
train_pool = Pool(X_train, y_train, cat_features=cat_full_idx)
val_pool = Pool(X_test, y_test, cat_features=cat_full_idx)
model_es = CatBoostClassifier(
iterations=1000,
learning_rate=0.05,
depth=6,
cat_features=cat_full_idx,
eval_metric='AUC',
early_stopping_rounds=50,
verbose=100,
random_state=42
)
model_es.fit(train_pool, eval_set=val_pool)
print(f"\nMeilleure itération : {model_es.best_iteration_}")
print(f"Meilleur AUC : {model_es.best_score_['validation']['AUC']:.3f}")
Hyperparamètres
| Hyperparamètre | Valeur typique | Description |
|---|---|---|
iterations |
200-2000 | Nombre d’arbres. Utiliser avec early stopping |
learning_rate |
0.01-0.1 | Taux d’apprentissage. Plus petit = plus stable, plus lent |
depth |
4-10 | Profondeur max des arbres. CatBoost limite naturellement le surapprentissage |
l2_leaf_reg |
1-10 | Régularisation L2 sur les feuilles (comme reg_lambda dans XGBoost) |
random_strength |
0.1-10 | Facteur de réduction de variance des scores de split. Plus haut = plus de randomisation |
one_hot_max_size |
2-255 | Seuil au-delà duquel una feature catégorielle passe du one-hot au target encoding |
Avantages de CatBoost
- Gestion native des catégorielles : Pas besoin de LabelEncoder ou OneHotEncoder en amont. On passe directement les colonnes catégorielles à CatBoost, qui s’en charge. Gain de temps énorme en preprocessing.
- Ordered Target Statistics élimine le target leakage : Contrairement à LightGBM qui utilise un encodage simple des catégories, CatBoost empêche le modèle de voir le futur dans l’encodage. C’est plus sûr et plus fiable.
- Ordered Boosting réduit le surapprentissage : CatBoost est généralement plus stable que XGBoost et LightGBM sur les petits datasets grâce à ce mécanisme. Moins de risque de devoir tuner exhaustivement les hyperparamètres.
- Peu besoin de tuning : Les valeurs par défaut de CatBoost sont souvent très bonnes. Dans la pratique, CatBoost est le boosting qui nécessite le moins de grid search pour obtenir de bons résultats.
- Prédiction rapide : Le modèle CatBoost entraîné est un fichier binaire compact, et la phase de prédiction est très rapide, compatible avec les contraintes de production.
Limites de CatBoost
- Entraînement parfois lent : L’ordered boosting est plus coûteuse que le boosting standard. Sur des datasets très volumineux, CatBoost peut être 2-3x plus lent à l’entraînement que LightGBM.
- Mémoire élevée : Les arbres symétriques (catégoriels) de CatBoost demandent plus de mémoire que les arbres asymétriques de LightGBM. Sur des machines limitées, c’est un inconvénient.
- Moins populaire que XGBoost : Moins de tutoriels, moins de questions Stack Overflow, moins d’intégration dans les pipelines standards. La communauté est plus petite.
- Catégorielles à très haute cardinalité : Si une feature a des millions de modalités uniques, le target encoding même ordonné peut perdre en précision. Des techniques de binning peuvent être nécessaires.
- Installation parfois problématique : CatBoost nécessite un compilateur C++ pour l’installation sur certains environnements (notamment les versions anciennes de Python sous Windows).
4 cas d’usage concrets
1. Scoring de crédit avec données hétérogènes
Les données de scoring de crédit combinent des features numériques (revenu, nombre de prêts) et des features catégorielles (type d’emploi, statut marital, région). CatBoost gère cette mixité sans préprocessing, et son ordered boosting évite les biais de surapprentissage critiques dans le domaine financier.
2. Recommandation de contenu avec données catégorielles riches
Pour les systèmes de recommandation (films, produits, articles), les features catégorielles dominent : genre, réalisateur, acteur, marque, catégorie produit. CatBoost capture les interactions entre ces catégories automatiquement, sans feature engineering manuel.
3. Prédiction de départ client (churn) avec catégorielles
Les données de churn contiennent souvent des variables comme le type d’abonnement, le canal d’acquisition, la localisation géographique — toutes catégorielles avec nombreuses modalités. CatBoost traite ces features directement et offre des performances compétitives avec un tuning minimal.
4. Classification de textes avec features mixtes
En classification de documents, on peut combiner les embeddings de texte (numériques) avec des métadonnées catégorielles (source, auteur, thème principal, langue). CatBoost fusionne ces deux types de features naturellement.
Conclusion
CatBoost se distingue dans l’écosystème des boostings par sa capacité à gérer nativement les features catégorielles, combinée avec un ordered boosting qui réduit significativement le surapprentissage. C’est le choix idéal quand les données contiennent beaucoup de catégories et que le temps de préprocessing est précieux.
En compétition, le trio XGBoost + LightGBM + CatBoost en stacking est souvent imbattable sur les données tabulaires. En production, CatBoost est privilégié quand la vitesse d’inférence et la robustesse au surapprentissage sont prioritaires.
Voir aussi
- Maîtrisez le Calcul de la Somme des Diviseurs avec Python : Guide Complet et Astuces Efficaces
- Créer un Jeu de Glissement en Python : Guide Complet et Astuces pour les Développeurs

