Random Forest, tutoriel pas à pas avec Python

Apprenez à créer un algorithme Random Forest avec Python grâce à ce tutoriel pas à pas

Cela faisait un moment que je voulais vous proposer un tutoriel complet avec Python pour réaliser un projet de Data Science assez simple. Je me lance donc dans cet article. Nous allons créer un modèle de prédiction avec un Random Forest en passant par l’ensemble de ces étapes :

  • Chargement des données
  • Exploration et visualisation des données
  • Création d’un échantillon d’apprentissage et de test
  • Phase d’apprentissage avec un algorithme Random Forest
  • Évaluation de la performance sur l’échantillon de test
  • Interprétation des résultats

Pour cela j’ai choisi un dataset disponible sur Kaggle qui contient l’indice de bonheur de chaque pays avec plusieurs variables explicatives.

Quelques rappels

Avant d’aller plus loin, voici quelques liens qui pourront vous être utiles si vous avez besoin de réviser un peu la théorie :

J’ai utilisé des données disponibles sur Kaggle : il s’agit du dataset World Happiness Report il contient plusieurs fichiers, j’ai utilisé celui de 2017 qui semble être le plus complet. Vous pouvez aussi retrouver l’ensemble de mon code sur Kaggle (peut être plus facile à lire que sur le blog)

C’est parti, notre objectif est de prédire l’indice de bonheur Happiness.Score

Set up

On commence par charger les librairies Python que nous allons utiliser

import pandas as pd  
import numpy as np
import pandas_profiling
import seaborn as sns
import geopandas as gpd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

Chargement des données

J’ai téléchargé les données, je les ai dézippé et j’ai conservé le fichier concernant l’année 2017. J’utilise la fonction read_csv de la librairie pandas pour charger mes données.

df = pd.read_csv("C:/Users/Happiness_2017.csv")
print("Le fichier a " + str(df.shape[0]) + " lignes et " + str(df.shape[1]) + " colonnes")
Le fichier a 155 lignes et 12 colonnes

Exploration

Liste et type de données

On analyse le contenu du fichier, le nom des colonnes et leur type, on explore les premières lignes du fichier

#Liste des colonnes et leur type 
df.dtypes
# 5 premières lignes du dataset
df.head(5)

Analyse de la qualité des données : pandas_profiling

On fait un état des lieux de la qualité des données :
– Données manquantes
– Données corrélées
– Valeurs extrêmes
– Statistiques descriptives (moyenne, écart-type, …)
– Distribution des variables

Rien de tel que la librairie pandas_profiling pour calculer tout cela automatiquement

pandas_profiling.ProfileReport(df)

Note : je vous présente ici uniquement une partie de la sortie pandas_profiling mais vous pouvez aller sur Github pour accéder au Notebook et voir le vrai résultat

Bilan pandas_profiling :

  • pandas_profiling a éliminé 2 variables : Whisker.high et Whisker.low qui sont fortement corrélées avec Happiness.Score. Effectivement, quand on regarde la définition de ces 2 variables on voit que ces 2 variables correspondent à l’intervalle de confiance de Happiness.Score. On peut donc les écarter pour notre analyse. On peut également supprimer Happiness.Rank
  • Aucune valeur manquante
  • 9 variables numériques et 1 variable textuelle (on avait déjà calculé cette info un peu plus haut)

Globalement ce dataset est propre. On regarde ensuite dans le détail chaque variable

Exploration & Visualisation

Avant de coder l’algorithme de prédiction du score de bonheur nous allons faire un peu d’exploration du jeu de données. L’idée est de mieux comprendre les liens entre les différentes variables et leur lien avec la variable à prédire Happiness.Score. Cette première étape descriptive est importante, elle vous permettra de mieux comprendre les résultats de votre algorithme et vous pourrez vous assurer que tout est cohérent.

Analyse des corrélations

# Matrice des corrélations : 
cor = df.corr() 
sns.heatmap(cor, square = True, cmap="coolwarm",linewidths=.5,annot=True )
#Pour choisr la couleur du heatmap : https://matplotlib.org/examples/color/colormaps_reference.html

Le heatmap permet de représenter visuellement les corrélations entre les variables.
Plus la valeur est proche de 1 (couleur rouge foncé) plus la corrélation est positive et forte. Au contraire plus la corrélation est proche de 0 (bleu foncé) plus la corrélation est négative et forte.

Constats :

Corrélations avec la variable cible Happiness.score :

  • Happiness.score est correlé positivement avec Economy.GDP.per.Capita., Family et Health..Life.Expectancy. (donc globalement quand l’indicateur family augmente, Happiness.score augmente aussi)
  • Happiness.score est correlé négativement avec Generosity
  • Pour les autres variables la corrélation est plus faible

Corrélations entre les autres variables :

  • 2 variables semblent assez correlées positivement : Health..Life.Expectancy. et Economy..GDP.per.Capita.
  • Générosite et Dystopia.Residual sont correlées négativement avec la plupart des variables

Géolocalisation

#Chargement du fonds de carte 
# Dispo ici https://tapiquen-sig.jimdofree.com/english-version/free-downloads/world/
map_df = gpd.read_file('C:/Users/World_Countries.shp')

#Jointure avec nos données (on ne conserve que Country et Happiness.Rank)
map_df = map_df.set_index('COUNTRY').join(df[['Country','Happiness.Score']].set_index('Country'))
map_df.dropna(inplace=True)
map_df.reset_index(inplace=True)

#Préparation de la carte
# on fixe les seuils pour la couleur
vmin, vmax = 0, 8
# création de la figure et des axes
fig, ax = plt.subplots(1, figsize=(18, 5))

# Création de la carte
map_df.plot(column='Happiness.Score', cmap='Blues', linewidth=0.8, ax=ax, edgecolor='0.8')
# On supprime l'axe des abscisses
ax.axis('off')

# On ajoute un titre
ax.set_title('Happiness.Score par pays', fontdict={'fontsize': '16', 'fontweight' : '2'})

# On créé la légende
sm = plt.cm.ScalarMappable(cmap='Blues', norm=plt.Normalize(vmin=vmin, vmax=vmax))
sm._A = []

# On ajoute la légende
cbar = fig.colorbar(sm)

Data prep

Le Dataset est de bonne qualité, il y a peu de travail à faire ici :

  • Transformer country en index puisqu’il s’agit de l’identifiant unique
  • Supprimer Happiness.Rank, Whisker.high et Whisker.low
# On transforme Country en index
pd.DataFrame.set_index(df, 'Country',inplace=True)

# On supprime 3 colonnes
df.drop(columns =['Happiness.Rank','Whisker.high', 'Whisker.low' ], inplace=True)

Modélisation

On transforme les données en Numpy arrays pour pouvoir les utiliser dans le modèle

#On stocke Happiness.Score (la variable à prédire) dans cible
cible = np.array(df['Happiness.Score'])

#On supprime Happiness.Score du dataset
df= df.drop('Happiness.Score', axis = 1)

#On conserve les noms de variable à part
liste_variables = list(df.columns)

#On convertit le dataset en array
df = np.array(df)

Split du dataset en train et test

On choisit de faire l’apprentissage sur un échantillon d’apprentissage de 75% des données et de faire le test sur 25% des données. On va également séparer la variable à prédire Happiness.Score des variables de prédiction

#On créé 4 dataset : 
#   - x_train contient 75% de x  
#   - y_train contient le appiness.Score associé à x_train
# => x_train et y_train permettront d'entraîner l'algorithme
#
#   - x_test contient 25% de x  
#   - y_test contient le appiness.Score associé à x_test
# => x_test et y_test permettront d'évaluer la performance de l'algorithme une fois entrainé sur le train

x_train,x_test,y_train,y_test=train_test_split(df,cible,test_size=0.25, random_state=2020)

Apprentissage

J’ai choisi d’utiliser un algorithme Random Forest.

#On importe l'algorithme à partir de sklearn
from sklearn.ensemble import RandomForestRegressor

#On créé un Random Forest de 100 arbres 
rf = RandomForestRegressor(n_estimators = 100, random_state = 2020)

#Et on lance le training sur notre dataset de train
rf.fit(x_train, y_train)

Test

#On applique le modèle que l'on vient 
#d'entraîner sur l'échantillon de test
predictions = rf.predict(x_test)
#On va calculer plusieurs erreurs entre la valeur prédite et le score de bonheur réel (que nous avions stocké dans y_test)
#     - MAE : Mean Asolute Error
#     - MAPE : Mean Absolute Percentage Error 

# MAE 
erreurs = abs(predictions - y_test)
print('Mean Absolute Error:', round(np.mean(erreurs), 2))
Mean Absolute Error: 0.32

La moyenne des erreurs est de 0,32 donc en moyenne on arrive à prédire le score de bonheur à 0.32 près

# MAPE
mape = 100 * (erreurs / y_test)
print('Mean Absolute Percentage Error :', round(np.mean(mape), 2), '%.')
Mean Absolute Percentage Error : 6.13 %.

Interprétation des résultats

On calcule les variables d’importance du modèle, c’est à dire celles qui contribuent le plus

importances = rf.feature_importances_
indices = np.argsort(importances)

# style du graphique 
plt.style.use('fivethirtyeight')
%matplotlib inline

plt.figure(1)
plt.title('Feature Importances')
plt.barh(range(len(indices)), importances[indices], color='b', align='center')
plt.yticks(range(len(indices)), [liste_variables[i] for i in indices])
plt.xlabel('Relative Importance')

Ce dernier graphique nous apprend que les 2 variables qui contribuent le plus à notre modèle sont Economy..GDP.per.Capita et Health..Life.Expectancy

Voilà si vous êtes allé jusqu’au bout de ce tutoriel vous avez intégralement prédit le score Happiness.Score grâce à un algorithme Random Forest en commençant par l’exploration des données, la data prep, la modélisation, le test et l’interprétation des résultats.

Et si vous voulez varier les plaisirs vous pouvez aussi coder un Random Forest avec R

Un commentaire sur « Random Forest, tutoriel pas à pas avec Python »

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s