.. _td2apipelinetreeselectionenoncerst: ================================================================= 2A.ml - Pipeline pour un réduction d’une forêt aléatoire - énoncé ================================================================= .. only:: html **Links:** :download:`notebook `, :downloadlink:`html `, :download:`python `, :downloadlink:`slides `, :githublink:`GitHub|_doc/notebooks/td2a_ml/td2a_pipeline_tree_selection_enonce.ipynb|*` Le modèle Lasso permet de sélectionner des variables, une forêt aléatoire produit une prédiction comme étant la moyenne d’arbres de régression. Cet aspect a été abordé dans le notebook `Reduction d’une forêt aléatoire `__. On cherche à automatiser le processus. .. code:: ipython3 from jyquickhelper import add_notebook_menu add_notebook_menu() .. contents:: :local: .. code:: ipython3 %matplotlib inline Datasets -------- Comme il faut toujours des données, on prend ce jeu `Diabetes `__. .. code:: ipython3 from sklearn.datasets import load_diabetes data = load_diabetes() X, y = data.data, data.target .. code:: ipython3 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y) Forêt aléatoire suivi de Lasso ------------------------------ La méthode consiste à apprendre une forêt aléatoire puis à effectuer d’une régression sur chacun des estimateurs. .. code:: ipython3 import numpy from sklearn.ensemble import RandomForestRegressor from sklearn.linear_model import Lasso # Apprentissage d'une forêt aléatoire clr = RandomForestRegressor() clr.fit(X_train, y_train) # Récupération de la prédiction de chaque arbre X_train_2 = numpy.zeros((X_train.shape[0], len(clr.estimators_))) estimators = numpy.array(clr.estimators_).ravel() for i, est in enumerate(estimators): pred = est.predict(X_train) X_train_2[:, i] = pred # Apprentissage d'une régression Lasso lrs = Lasso(max_iter=10000) lrs.fit(X_train_2, y_train) lrs.coef_ .. parsed-literal:: array([ 0.01058919, 0.05879275, -0.00490468, 0.0422317 , 0.02061981, 0.05832323, 0.04902792, -0.02386671, -0.00783027, -0.02905091, -0.05936758, -0.03081102, -0.00874234, -0.01032493, -0.00215755, 0.02104254, -0.06726193, 0.00863015, -0.00657562, 0.01915455, 0.1103515 , 0.03127041, 0.0059957 , 0.01318572, -0.02425179, 0.02444136, -0.01270415, 0.00860503, -0.01053657, -0.0044742 , -0.01316523, 0.01369104, -0.00739582, -0.02240202, -0.0049985 , 0.08646501, 0.00866649, -0.00228254, 0.02181667, 0.01934537, -0.00796704, -0.00372213, 0.02581304, -0.01812068, 0.04921884, 0.04735237, -0.01544872, 0.00383606, 0.03220245, 0.04162666, 0.00815848, 0.04327313, 0.03816147, -0.00254619, 0. , -0.03287036, -0.04364327, 0.00691009, -0.00819448, 0.00571863, -0.0085195 , 0.03282482, -0.041993 , 0.04787454, 0.01832266, 0.03145652, 0.013905 , 0.00592087, 0.01296335, 0.01339059, 0.01104395, -0.0004973 , 0.05065905, 0.01915292, 0. , 0.00598882, 0. , 0.03658216, -0.01576201, 0.00131738, 0.07700475, 0.03661206, 0.0100858 , 0.0201148 , 0.08337645, 0.01867529, 0.00236212, -0.00237683, 0.06146853, 0.05481785, 0.0629231 , -0.00304007, -0.03835209, 0.00739201, 0.00431521, 0.01388169, 0.02238382, 0.01769634, 0.01612737, 0.01166434]) Nous avons réussi à reproduire le processus dans son ensemble. Pas toujours simple de se souvenir de toutes les étapes, c’est pourquoi il est plus simple de compiler l’ensemble dans un `pipeline `__. Exercice 1 : Premier pipeline ----------------------------- Peut-être trouverez-vous tout de suite un `pipeline `__ qui fonctionne. La partie difficile est la partie qui produit le vecteur des sorties de chaque arbre de régression. La première piste que j’ai explorée est un `FunctionTransformer `__. Exercice 2 : Second pipeline ---------------------------- La première idée de marche pas vraiment… On décide alors de déguiser la forêt aléatoire en un transformeur. .. code:: ipython3 class RandomForestRegressorAsTransformer: def __init__(self, **kwargs): self.rf = RandomForestRegressor(**kwargs) def fit(self, X, y): # ... return self def transform(self, X): # ... # return les prédiction de chaque arbre pass # Tout ça pour écrire ce qui suit... trrf = RandomForestRegressorAsTransformer() trrf.fit(X_train, y_train) trrf.transform(X_train) Il reste à écrire le pipeline correspondant à la séquence d’apprentissage décrit quelque part dans ce notebook. .. code:: ipython3 from sklearn.pipeline import Pipeline pipe = Pipeline(steps=[ ('name', 'passthrough'), # ... ]) pipe.fit(X_train, y_train) .. raw:: html
Pipeline(steps=[('name', 'passthrough')])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Exercice 3 : GridSearchCV ------------------------- Comme l’ensemble des traitements sont maintenant dans un seul pipeline que *scikit-learn* considère comme un modèle comme les autres, on peut rechercher les meilleurs hyper-paramètres du modèle, comme le nombre d’arbres initial, le paramètre *alpha*, la profondeur des arbres… Tout ça avec la classe `GridSearchCV `__. Vous devriez tomber sur un message disant que la classe ``RandomForestRegressorAsTransformer`` a besoin de la méthode *set_params*\ … Un indice : ``def set_params(self, **params): self.rf.set_params(**params)``. Exercice 4 : nombre de coefficients non nuls -------------------------------------------- Il ne reste plus qu’à trouver le nombre de coefficients non nuls du meilleur modèle, donc le nombre d’arbres conservés par le modèle.