foret aleatoire python

Forêt aléatoire avec python et scikit-learn

Emmanuel Jakobowicz Mis à jour le : 27 avril 2021 méthode, python 2 Comments

Une forêt aléatoire ou random forest est une méthode d’apprentissage supervisé extrêmement utilisée par les data scientists. En effet, cette méthode combine de nombreux avantages dans le cadre d’un apprentissage supervisé. Dans cet article, je vais vous présenter l’approche et une application avec le langage python et le package de machine learning, scikit-learn.

La forêt aléatoire – forces et faiblesses

Ses forces :

  • Elle permet d’obtenir de bons résultats assez rapidement
  • Elle est basé sur des principes simples
  • Elle est simplement implémentable
  • Les calculs de l’apprentissage peuvent être facilement distribués

Ses faiblesses :

  • Son temps d’apprentissage peut parfois être un peu lent
  • Elle est souvent dépassée par d’autres méthodes plus difficiles à mettre en place mais souvent plus efficaces telles que les GBM (gradient boosting machine)

Cette méthode reste l’une des plus utilisée en machine learning.

La forêt aléatoire – principes

Comme son nom l’indique, cette méthode est basée sur la notion de forêt et que ce soit en data science ou dans la réalité, une forêt est constitué des mêmes éléments : des arbres. Avant de comprendre la notion de forêt aléatoire, il faut donc comprendre la notion d’arbre.

Les arbres de décision

L’apprentissage par arbre de décision est une approche permettant de construire des arbres qui serviront de modèle prédictif. Ainsi un arbre ressemble à cela :

Il est composé de feuilles et de branches. On part du sommet de l’arbre et on descend en empruntant les feuilles jusqu’à arriver en bas de l’arbre ce qui va permettre de prendre une décision.

La construction de l’arbre est basée sur des algorithmes permettant d’optimiser un critère afin d’obtenir des séparations les plus « pures » possibles. L’apprentissage par arbre de décision consiste en l’apprentissage de l’arbre en utilisant vos données. Chaque branche est créée de manière à séparer le mieux possibles les différentes modalités de la cible de votre apprentissage supervisé.

Un arbre possède de nombreux avantages, notamment une interprétabilité extrêmement grande. Néanmoins, il possède une très grande faiblesse, sa stabilité. En effet, un arbre est extrêmement sensible à de petits changements dans les données d’apprentissage. Si vous changez légèrement les données, l’arbre peut en être totalement modifié. Afin de contrer cette faiblesse, les forêts aléatoires ont été créées.

La forêt

Le principe de la forêt aléatoire est simple, il s’agit de multiplier les arbres. Mais bien évidemment, si vous créez 100 arbres sur les mêmes données, vous allez obtenir 100 fois le même arbre. Nous allons donc modifier légèrement les données pour chacun des 100 arbres.

Le rééchantillonnage par bootstrap

Afin de modifier légèrement les données, nous allons utiliser une méthode bien connue des statisticiens : le bootstrap. Il s’agit d’une méthode qui permet, à partir d’un échantillon, de construire de nouveaux échantillons par tirage aléatoire avec remise. Ceci revient à faire pour le cas d’un jeu de données avec 10000 lignes et 100 colonnes :

  1. On a un échantillon original de 10000 lignes et 100 colonnes
  2. On tire aléatoirement avec remise 10000 lignes (ceci veut dire qu’on aura 10000 lignes dans le nouvel échantillon mais avec certaines lignes de l’échantillon original plusieurs fois et d’autres pas du tout)
  3. On répète l’étape 2 autant de fois qu’on a besoin d’arbres dans la forêt

Le bootstrap a de nombreuses propriétés très intéressantes étudiées en détails par Efron dans ses ouvrages et ici.

L’apprentissage de la forêt

Une fois les échantillons générés, on peut construire les arbres. Pour cela, on va tirer aléatoirement certaines colonnes de nos données de façon à ne pas utiliser toutes les colonnes simultanément et apprendre sur chaque échantillon bootstrap. On aura donc 100 arbres qui seront tous légèrement différents.

Une fois l’apprentissage terminé, les règles de décisions des 100 arbres sont stockées afin d’être appliquées en mode prédictif. Ceci revient à faire passer une nouvelle observation dans les 100 arbres et chaque arbre va définir une classe d’appartenance, un vote de majorité est appliqué pour établir la classe prédite.

Mise en œuvre avec python

On va utilise python pour mettre en œuvre une forêt aléatoire. On commence par charger les packages dont on a besoin :

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

On récupère des données, nous utiliserons des données classiques d’apprentissage supervisé, il s’agit d’un modèle permettant de prédire la couleur d’un vin en fonction de ses caractéristiques physico-chimiques.

data = pd.read_csv("https://www.stat4decision.com/wine_data.csv", index_col = 0)
data["type"].value_counts()
0    4898
1    1599
Name: type, dtype: int64

On a donc 4898 vins blancs et 1599 vins rouges.

data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 6497 entries, 0 to 1598
Data columns (total 13 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   fixed acidity         6497 non-null   float64
 1   volatile acidity      6497 non-null   float64
 2   citric acid           6497 non-null   float64
 3   residual sugar        6497 non-null   float64
 4   chlorides             6497 non-null   float64
 5   free sulfur dioxide   6497 non-null   float64
 6   total sulfur dioxide  6497 non-null   float64
 7   density               6497 non-null   float64
 8   pH                    6497 non-null   float64
 9   sulphates             6497 non-null   float64
 10  alcohol               6497 non-null   float64
 11  quality               6497 non-null   int64  
 12  type                  6497 non-null   int64  
dtypes: float64(11), int64(2)
memory usage: 710.6 KB

On n’a pas de données manquantes et on a 11 variables explicatives pour notre modèle et une cible (type).

Séparation apprentissage / test

On va donc séparer nos données en un échantillon d’apprentissage pour apprendre notre modèle et un échantillon test pour tester l’efficacité de la forêt aléatoire.

y = data["type"]
x = data.drop("type", axis = 1)
x_train, x_test, y_train, y_test  = train_test_split(x, 
                                                     y, 
                                                     test_size=0.25, 
                                                     random_state=42)

On utilise un échantillon de test représentant 25% des données.

Apprentissage de la forêt aléatoire

On va utiliser scikit-learn pour construire notre forêt aléatoire, on utilise donc la classe RandomForestClassifier de scikit-learn et on crée un objet à partir de cette classe. C’est à ce moment que nous allons définir ce qu’on appelle les hyperparamètres du modèle. Il s’agit de paramètres tels que le nombre d’arbres dans la forêt qui doivent être définis en amont de l’apprentissage.

modele_rf = RandomForestClassifier(
     n_estimators=100,
     criterion='gini',
     max_depth=None,
     min_samples_split=2,
     min_samples_leaf=1,
     min_weight_fraction_leaf=0.0,
     max_features='auto',
     max_leaf_nodes=None,
     min_impurity_decrease=0.0,
     bootstrap=True,
     oob_score=False,
     n_jobs=None,
     random_state=None,
     verbose=0,
     warm_start=False,
     class_weight=None,
     ccp_alpha=0.0,
     max_samples=None,)

Tous ces hyperparamètres ont des valeurs par défaut que nous modifions rarement, mais il est utile de les comprendre. En voici un description rapide :

  • n_estimators : il s’agit du nombre d’arbres dans la forêt
  • criterion : il s’agit du critère utilisé pour construire les arbres et séparer les branches des arbres
  • max_depth : il s’agit de la profondeur maximale des arbres utilisés (le nombre de niveaux dans l’arbre de décision)
  • min_sample_split : il s’agit du nombre d’échantillons minimal dans une feuille pour refaire une séparation
  • min_samples_leaf : il s’agit du nombre d’échantillons minimal pour créer une feuille
  • min_weight_fraction_leaf : il s’agit de la fraction du nombre total d’échantillon minimal pour créer une feuille
  • max_features : il s’agit du nombre de colonnes sélectionnées pour chaque arbre (par défaut on prend la racine carré du nombre de colonnes)
  • max_leaf_nodes : il s’agit du nombre maximal de feuilles
  • min_impurity_decrease : il s’agit de la baisse minimale du critère d’impureté pour faire une séparation
  • bootstrap : paramètre pour utiliser du bootstrap, si il est à False, le même échantillon est pris pour chaque arbre
  • n_jobs ; nombre de traitements à effectuer en parallèle
  • random_state : graine aléatoire
  • warm_start : ceci permet de repartir du résultat du dernier apprentissage pour faire l’apprentissage
  • class_weights : il s’agit des poids associés à chaque classe si cela a un sens
  • max_samples : si vous voulez réduire le nombre d’observations dans vos échantillons bootstrap

Bien entendu, vous ne toucherez à quasiment aucun de ces hyperparamètres mais ils vous permettent néanmoins d’améliorer votre modèle, le choix de ces hyperparamètres se fait au moment de l’ajustement des hyperparamètres du modèle (on utilise généralement la classe GridSearchCV pour cela).

Nous avons donc construit un objet forêt aléatoire, nous devons maintenant effectuer l’apprentissage :

modele_rf.fit(x_train, y_train)

On peut afficher l’importance des variables de notre modèle de forêt aléatoire :

pd.DataFrame(modele_rf.feature_importances_,
              index = x_train.columns, 
              columns = ["importance"]).sort_values(
     "importance", 
     ascending = False)
Importance des variables forêt aléatoire

On voit que la variable la plus importante (au sens de son importance dans les arbres générés) est total sulfur dioxyde. On voit que la moins importante est la qualité qui a été évaluée par des juges.

Validation du modèle et prédictions

Une fois notre modèle appris, il faut le valider. Pour cela, on va utiliser les données de test et des indicateurs très classiques.

On compare donc la valeur prédite par le modèle avec la valeur dans les données. Il s’agit ici de comparer la couleur du vin prédite par le modèle et celle observée dans notre échantillon test.

Le premier indicateur utilisé est le pourcentage de bien classé aussi appelé accuracy :

from sklearn.metrics import accuracy_score, confusion_matrix
print(f"Le pourcentage de bien classés est de : {accuracy_score(y_test, modele_rf.predict(x_test))*100} %")
Le pourcentage de bien classés est de : 99.56923076923077 %

Cet indicateur mesure le nombre de vins bien classés (rouge ou blanc) dans notre échantillon test. On voit qu’on a ici 99,56% de vins bien classés, ce qui traduit une très bonne qualité prédictive de notre modèle.

Pour avoir une analyse plus fine des résultats, on peut utiliser la matrice de confusion. Celle-ci donne plus de détails sur les vins qui sont mal classés :

pd.DataFrame(confusion_matrix(y_test, modele_rf.predict(x_test)),
             index = ["blanc_données", "rouge_données"],
             columns = ["blanc_predit", "rouge_predit"])
Matrice de confusion forêt aléatoire

On voit ici qu’un vin blanc (blanc_données) a été considéré comme rouge par le modèle (rouge_predit) et que 6 vins rouges (rouge_données) ont été prédits comme blancs par le modèle (blanc_predit).

Le notebook de cette article est disponible sur GitHub ici.

Aller plus loin

Il s’agit ici de la première étape de construction du modèle. On devra ensuite comparer à d’autres modèles et ajuster les hyperparamètres. Dans notre cas, les forêts aléatoires ont bien répondu à notre problématique et nous pouvons utiliser ce modèle pour prédire la couleur du vin à partir des caractéristiques physico-chimiques.

Si vous désirez aller plus loin dans l’apprentissage des méthodes de machine learning, inscrivez-vous à nos différentes formations :

Partager cet article

Comments 2

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.