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 x 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