CatBoost !

Introduction

Connaissiez-vous le dernier algorithme de Boosting de gradient à la mode: CatBoost ? Non ?

sans doute connaissez-vous déjà le XGBoost mais aussi le bon vieux Light GBM. Il est donc temps de voir ce que ce dernier arrivé dans la famille des booster de gradient a à nous offrir de plus (ou moins) que ses prédécesseurs.

Cet algorithme nous vient tout droit de la société Russe Yandex (qui n’est qu’autre qu’un moteur de recherche et un portail russe, d’ailleurs Yandex est le moteur par défaut de Mozilla Firefox en Russie et en Turquie !). Il a été mis à la disposition de la communauté Open-Source en avril 2017 et s’avère particulièrement performant dans certains cas de figures.

Installation

L’installation sous Python (et/ou R) est plutôt simple:

Si vous utilisez Anaconda (comme moi), lancez une ligne de commande et tapez:

conda config --add channels conda-forge
conda install catboost
pip install ipywidget
# pour activer les extensions Jupyter tapez aussi :
jupyter nbextension enable --py widgetsnbextension

En utilisant simplement l’utilitaire pip :

pip install catboost
pip install ipywidget
# pour activer les extensions Jupyter tapez aussi :
jupyter nbextension enable --py widgetsnbextension

Voilà CatBoost est prêt à l’emploi, lancez votre notebook Jupyter et tapez en première ligne :

import catboost as cb

Les variables catégorielles avec CatBoost

CatBoost a pour particularité (par rapport à ses concurrents) d’affecter des index de colonnes aux données catégorielles afin qu’elles puissent être encodé via encodage One-Hot à l’aide du paramètre one_hot_max_size . Si rien n’est transmit dans l’argument cat_features, CatBoost traitera alors toutes les colonnes comme des champs numériques « classiques ».

Attention :

  • Si une colonne contenant des valeurs de chaîne n’est pas fournie dans cat_features, CatBoost sort en erreur.
  • Les colonnes de type int sont traités comme numérique dans tous les cas
  • il faut explicitement spécifier la colonne dans cat_features pour que l’algorithme la traite comme catégorielle.

Excellente nouvelle, et pour faire simple … l’algorithme va prendre en charge pour nous l’encodage one-hot 🙂

CatBoost vs XGBoost

Et si nous comparions les deux algorithmes de boosting de Gradient les plus utilisés : XGBoost vs CatBoost. Pour celà je vous invite à relire mon article sur XGBoost car nous allons reprendre exactement le même cas d’usage: qui je vous le rappelle était le jeu de données du Titanic.

Comme nous l’avons vu dans le chapitre précédent, nous n’avons pas à nous préocuper de l’encodate one-hot, donc nous laisserons nos variables vatégorielles (Cabine, classe, etc.) telles quelles et laisserons CatBoost s’en occuper. Notre fonction de préparation de données s’en retrouve allégée de la sorte :

import catboost as cb
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
import xgboost as xgb

train = pd.read_csv("../titanic/data/train.csv")
test = pd.read_csv("../titanic/data/test.csv")

def dataprep(data):
    cabin = data['Cabin'].fillna('X').str[0]
    # Age 
    age = data['Age'].fillna(data['Age'].mean())
    emb = data['Embarked'].fillna('X').str[0]
    # Prix du billet / Attention une donnée de test n'a pas de Prix !
    faresc = pd.DataFrame(MinMaxScaler().fit_transform(data[['Fare']].fillna(0)), columns = ['Prix'])
    # Classe
    pc = pd.DataFrame(MinMaxScaler().fit_transform(data[['Pclass']]), columns = ['Classe'])
    
    dp = data[['SibSp', 'Sex']].join(pc).join(faresc).join(age).join(cabin).join(emb)
    return dp

Xtrain = dataprep(train)
Xtest = dataprep(test)
y = train.Survived

Remarquez quand même que nous devons gérer encore les N.A. (vide ou Nulls), sans quoi l’entraînement va planter, ce qui est plutôt normal finalement.

Entraînons maintenant notre modèle. Avant tout nous devons appeler CatBoost en lui présentant ses hyper-parametres mais aussi en lui précisant quelles colonnes sont catégorielles. C’est le rôle du vecteur cat_features (ci-dessous) qui précise le rang des colonnes de ce type. Il ne faudra juste pas oublier de passer ce vecteur à la fonction d’entraînement fit() pour sa prise en compte.

Ensuite une liste (params) propose les paramètres.

cat_features = [1,5,6]
params = {'depth': [4, 7, 10],
          'learning_rate' : [0.03, 0.1, 0.15],
          'l2_leaf_reg': [1,4,9],
          'iterations': [300]}
cbc = cb.CatBoostClassifier()
cbc.fit(Xtrain, y, cat_features)

Le modèle est maintenant entraîné, regardons son résultat :

p_cbc = cbc.predict(Xtrain)
print ("Score Train -->", round(cbc.score(Xtrain, y) *100,2), " %")
Score Train --> 87.77  %

un 87.7 % s’avère plus que raisonnable pour un premier test 🙂

Changeons quelques paramètres :

clf = cb.CatBoostClassifier(eval_metric="AUC", 
                            depth=10, 
                            iterations= 500, 
                            l2_leaf_reg= 9, 
                            learning_rate= 0.15)
clf.fit(Xtrain, y, cat_features)
print ("Score Train -->", round(clf.score(Xtrain, y) *100,2), " %")
Score Train --> 92.59  %

Hum c’est mieux (peut être trop d’ailleurs) car un tel score se doit d’être validé : attention au sur-entraînement ! Chose d’ailleurs que l’algorithme sait gérer (via des paramètres). En tout cas cet algorithme s’avère très intéressant si du moins on ajuste bien les variables en entrée.

Comme d’habitude les sources ci-dessus sont disponibles sur GitHub.

Conclusion

En quelques points:

  • Catboost est un algorithme très performant mais aussi plus lent que ses concurrents.
  • Il ne possède pas d’autre booster que les arbres de disponibles
  • Il peut être utilisé pour des tâches de régression ou classification
  • Cet algorithme possède plusieurs paramètres pour l’apprentissage des variables catégorielles (qu’il gère automatiquement comme nous l’avons vu)
  • Il possède des paramètres de détection de sur-apprentissage.
Partager cet article

2 Replies to “CatBoost !”

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.