Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn

Introduction

La Forêt aléatoire est un algorithme d'apprentissage supervisé basé sur des arbres qui utilise un ensemble de prédictions de nombreux arbres de décision, soit pour classer un point de données, soit pour déterminer sa valeur approximative. Cela signifie qu'il peut être utilisé pour la classification ou la régression.

Lorsqu'elle est appliquée pour la classification, la classe du point de données est choisie en fonction de la classe qui a été la plus votée par les arbres ; et lorsqu'il est appliqué pour la régression, la valeur du point de données est la moyenne de toutes les valeurs produites par les arbres.

Une chose importante à retenir lors de l'utilisation des forêts aléatoires est que le nombre d'arbres est un hyperparamètre et qu'il sera défini avant d'exécuter le modèle.

Lorsque vous travaillez dans la science des données, l'une des raisons pour lesquelles un modèle de forêt aléatoire a été choisi pour un projet spécifique peut être liée à la capacité de regarder des arbres ensemble et de comprendre why une classification a été faite, ou why une valeur a été donnée - c'est ce qu'on appelle explicabilité.

Considérant les algorithmes basés sur des arbres, tenter d'expliquer un modèle peut se faire de plusieurs manières, en affichant et en regardant chaque arbre (peut être difficile si le modèle a 200 arbres ou plus), en utilisant Valeurs Shapley (ou SHAP), en examinant les caractéristiques les plus prises en compte par le modèle, en utilisant LIME pour étudier les relations entre l'entrée et la sortie du modèle, etc. Habituellement, une combinaison de toutes les méthodes est employée.

Dans ce guide rapide, nous nous concentrerons sur la création d'un tableau des caractéristiques considérées comme importantes pour que le modèle prenne une décision lors de la classification des pingouins. C'est ce qu'on appelle enquêter sur importance de la caractéristique, et peuvent être transmises à d'autres membres de l'équipe (techniques et non techniques) pour offrir un aperçu de la façon dont les décisions sont prises.

Pour ce faire, importons les bibliothèques nécessaires, chargeons le jeu de données Palmer Penguins, divisons les données, créons le modèle, obtenons les importances des caractéristiques et utilisons Seaborn pour les tracer ! Nous n'approfondirons pas grand-chose sur les données, l'EDA ou le modèle lui-même - c'est le sujet du guide dédié.

Remarque: Vous pouvez télécharger l'ensemble de données depuis GitHub ou directement depuis le code.

Importation de bibliothèques

Commençons par importer quelques bibliothèques que nous utiliserons :


import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier


raw_data_url = "https://gist.githubusercontent.com/cassiasamp/197b4e070f5f4da890ca4d226d088d1f/raw/38c9d4906ed121481b4dc201fa2004f2b3d0065f/penguins.csv"
df = pd.read_csv(raw_data_url)

Fractionner les données

Séparons les données pour l'entraînement et les tests :


df = df.dropna().drop("rowid", axis=1)


y = df["species"]
X = df[["bill_length_mm", "bill_depth_mm", "flipper_length_mm"]]


X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

Obtention de l'importance des fonctionnalités

Enfin, nous pouvons former un modèle et exporter les importances des fonctionnalités avec :


rf = RandomForestClassifier()


rf.fit(X_train, y_train)


rf.feature_importances_

Cela produit:

array([0.41267633, 0.30107056, 0.28625311])

Ce sont les valeurs des fonctionnalités, pour voir les noms des fonctionnalités, exécutez :


rf.feature_names_in_

Cela se traduit par le nom correspondant de chaque fonctionnalité :

array(['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm'],
      dtype=object)

Cela signifie que la caractéristique la plus importante pour décider des classes de péguins pour ce modèle particulier était le bill_length_mm!

L'importance est relative à la mesure dans laquelle les données sont séparées dans chaque division de nœud - dans ce cas, la mesure est donnée par le Index de Gini – la valeur de gini est ensuite pondérée par le nombre de lignes qui ont été divisées lors de l'utilisation de la bill_length_mm caractéristique et moyennée sur les 100 arbres de l'ensemble. Le résultat de ces étapes compte pour 0.41267633, soit plus de 40% dans ce cas.

Visualiser l'importance des fonctionnalités

Une manière courante de représenter les valeurs d'importance consiste à utiliser les discussions de barre. Commençons par créer un cadre de données avec les noms des fonctionnalités et leurs importances correspondantes, puis visualisons-les à l'aide de Seaborn. barplot():


importances_df = pd.DataFrame({"feature_names" : rf.feature_names_in_, 
                               "importances" : rf.feature_importances_})
                             

g = sns.barplot(x=importances_df["feature_names"], 
                y=importances_df["importances"])
g.set_title("Feature importances", fontsize=14);                          

Conseils: Une bonne pratique lors de la présentation des informations consiste à classer les valeurs par ordre croissant ou décroissant. Dans ce cas, les données sont déjà ordonnées, la première valeur étant la première que nous voulons connaître. Lorsque ce n'est pas le cas, vous pouvez commander le dataframe avec sort_values. Cela peut être fait sur n'importe quelle colonne dans l'ordre croissant ou décroissant : importances_df.sort_values(by="importances", ascending=False).

Lorsque l'on regarde ce premier graphique, il est plus difficile d'interpréter la valeur de l'importance de chaque caractéristique. Il est évident que la longueur du bec est plus grande que les deux autres barres, mais pas exactement que le bill_depth_mm équivaut à 0.30107056et que le flipper_length_mm est 0.28625311. Ainsi, ce premier graphique peut être amélioré en affichant la valeur de chaque barre. Cela peut être fait en accédant à Seaborn's containers objet. Il stocke chaque information de barre et transmet les valeurs sous forme d'étiquettes de barre :

Consultez notre guide pratique et pratique pour apprendre Git, avec les meilleures pratiques, les normes acceptées par l'industrie et la feuille de triche incluse. Arrêtez de googler les commandes Git et en fait apprendre il!

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names")
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
    g.bar_label(value)

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Maintenant, nous pouvons voir chaque valeur d'importance clairement, ou presque clairement, parce que bill_length_mm la valeur est coupée par une ligne verticale qui fait partie de la bordure extérieure du graphique. Les bordures sont utilisées pour délimiter une zone afin d'attirer davantage l'attention sur elle, mais dans ce cas, nous n'avons pas besoin de délimiter, car il n'y a qu'un seul graphique. Supprimons la bordure et améliorons la lisibilité des chiffres :

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names")
                

sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
    g.bar_label(value)

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Le graphique semble plus facile à lire, mais les graduations sur l'axe X semblent flotter et nous avons déjà les valeurs avec les barres, nous pouvons donc supprimer les xticks:

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names")
sns.despine(bottom=True, left=True)


g.set(xticks=[])
g.set_title("Feature importances", fontsize=14)
for value in g.containers:
    g.bar_label(value)

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Remarquez qu'après avoir supprimé les tiques, les étiquettes Y et X sont un peu difficiles à lire. L'étiquette Y, feature_names, est vertical et en abscisse, il n'y a que importances. Étant donné que le titre indique déjà que le graphique est de Importance des fonctionnalités, nous pouvons également supprimer les étiquettes des axes :

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names")
sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
g.set(xticks=[])


g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
    g.bar_label(value)

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Vous pouvez voir à quel point ce graphique est plus propre, facile à lire et à comprendre en le comparant au premier. Il y a encore des choses que nous pouvons faire. Remarquez que les chiffres sont vraiment proches des barres, ce serait plus facile à lire s'il y avait un peu plus d'espace entre elles.

Un autre élément de cette intrigue sont les couleurs, lorsque des couleurs contrastées sont utilisées, elles transmettent une idée de séparation, à l'inverse, lorsque des couleurs similaires sont utilisées, elles communiquent une idée d'unité ou de parties d'un tout. Étant donné que les caractéristiques font toutes partie des pingouins, nous pouvons utiliser une couleur qui rend chaque barre distincte tout en conservant l'unité :

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names",
                
                
                palette="mako")
sns.despine(bottom=True, left=True)
g.set_title("Feature importances", fontsize=14)
g.set(xticks=[])
g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
    g.bar_label(value, 
                padding=2) 

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Si vous souhaitez rendre les résultats encore plus directs, vous pouvez modifier le titre et ajouter la conclusion. Ce que l'on sait, c'est que la longueur du bec était considérée comme la caractéristique la plus importante selon les critères dont nous avons discuté précédemment. Cela peut être la première information pour quelqu'un qui regarde l'intrigue, on pourrait dire que la longueur du bec du pingouin était la caractéristique la plus importante pour la classification des espèces dans le modèle de base Random Forest (RF) :

g = sns.barplot(data=importances_df, 
                x="importances", 
                y="feature_names", 
                palette="mako")
sns.despine(bottom=True, left=True)
g.set_title("The penguin's bill length was the most important feature for species classification (RF base model)", fontsize=14)
g.set(xticks=[])
g.set(xlabel=None)
g.set(ylabel=None)
for value in g.containers:
    g.bar_label(value, padding=2)

Voici le résultat final du tableau d'importance des fonctionnalités :

Obtenez l'importance des fonctionnalités pour les forêts aléatoires avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Conclusion

Dans ce guide - nous avons construit un classificateur de forêt aléatoire - et inspecté les importances des fonctionnalités qui ont été utilisées pour former le modèle dans le but de expliquer ce qu'un modèle a appris et ce qui affecte son raisonnement.

Horodatage:

Plus de Stackabuse