Formation des modèles d'arbres
Let's go !

4.2 Le Gradient Boosting Tree from scratch

Promis, c’est la dernière fois que je vous embête avec ça, mais pour moi implémenter un algorithme from scratch est la meilleure façon d’être sûr d’avoir bien compris son fonctionnement. 

Dans cette partie, nous allons implémenter l’algorithme de Gradient Boosting Tree from scratch en Python.

Pour plus de simplicité, nous n’allons pas implémenter l’algorithme d’arbre de décision mais utiliser ce qui est proposé par le package Sklearn. 

Si vous voulez avoir plus d’informations sur l’implémentation de l’arbre de décision, rendez-vous au premier chapitre.

A/ L'initialisation de la classe AdaBoost

Nous allons coder la classe du modèle qui va nous permettre d’entraîner nos modèles de Gradient Boosting Tree.

On va commencer par créer la fonction d’initialisation de la classe.

C’est à cette étape que l’on va demander à l’utilisateur de spécifier toutes les informations dont on a besoin pour entraîner notre modèle.

class GBTRegressor():
  def __init__(self, n_estimators=100, max_depth=1, random_state=None, 
               learning_rate=1.0, subsample=1, criterion='mse', splitter='best', 
               min_samples_split=2, min_samples_leaf=1, max_leaf_nodes=None, 
               min_impurity_decrease=0, ccp_alpha=0):
    self._n_estimators = n_estimators
    self._max_depth = max_depth
    self._random_state = random_state
    self._learning_rate = learning_rate
    self._subsample = subsample
    self._criterion = criterion
    self._splitter = splitter
    self._min_samples_split = min_samples_split
    self._min_samples_leaf = min_samples_leaf
    self._max_leaf_nodes = max_leaf_nodes
    self._min_impurity_decrease = min_impurity_decrease
    self._ccp_alpha = ccp_alpha
    self._model = dict()

B/ La fonction d'entraînement

La classe fit, va permettre d’entraîner un nombre d’arbres de notre forêt égal au nombre spécifié dans model.

  def fit(self, x, y):

    # Mettre les x dans la dimension adéquat (100, 1) plutôt que (100,)
    x = np.array(x).reshape(-1, 1)

    # Création du premier estimateur, une feuille qui contient la moyenne de la variable à prédire
    self._model[0] = np.mean(y)

    # Calcul des résidus
    self._residual = y - self._model[0]

    # Entraînement des arbres de la forêt
    for i in range(1, self._n_estimators+1) :

      # Initialiser le modèle d'arbre de décision
      estimator = DecisionTreeRegressor(max_depth=self._max_depth, 
                                             random_state=self._random_state, 
                                             criterion=self._criterion,
                                             splitter=self._splitter,
                                             min_samples_split=self._min_samples_split,
                                             min_samples_leaf=self._min_samples_leaf,
                                             max_leaf_nodes=self._max_leaf_nodes,
                                             min_impurity_decrease=self._min_impurity_decrease,
                                             ccp_alpha=self._ccp_alpha)
      
      # Entraîner le modèle sur les résidus
      self._model[i] = estimator.fit(x, self._residual)

      # Prédire la prédiction de la forêt actuel
      pred_tree = self._model[0] + self._learning_rate * np.sum([ self._model[j].predict(x) for j in range(1, i+1)], axis=0)

      # Calculer les nouveaux résidus
      self._residual =  y - pred_tree

C/ La fonction de prédiction

La classe predict utilise les données passées en paramètre dans et somme les prédictions de tous les arbres

  def predict(self, x):

    x = np.array(x).reshape(-1, 1)

    pred = self._model[0] + self._learning_rate * np.sum([ self._model[j].predict(x) for j in range(1, self._n_estimators+1) ], axis=0)

    return pred