Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn

Introduction

L'algorithme Random Forest est l'un des algorithmes les plus flexibles, les plus puissants et les plus largement utilisés pour classification et régression, construit comme un ensemble d'arbres de décision.

Si vous n'êtes pas familier avec ceux-ci - pas de soucis, nous couvrirons tous ces concepts.

Dans ce guide pratique détaillé, nous allons construire un intuition sur le fonctionnement des arbres de décision, comment l'assemblage stimule les classificateurs et les régresseurs individuels, ce que sont les forêts aléatoires et créez un classificateur et un régresseur de forêt aléatoire à l'aide de Python et Scikit-Learn, via un mini-projet de bout en bout, et répondez à une question de recherche.

Considérez que vous faites actuellement partie d'un groupe de recherche qui analyse des données sur les femmes. Le groupe a collecté 100 enregistrements de données et souhaite pouvoir organiser ces enregistrements initiaux en divisant les femmes en catégories : être enceinte ou non et vivre en zone rurale ou urbaine. Les chercheurs veulent comprendre combien de femmes seraient dans chaque catégorie.

Il existe une structure de calcul qui fait exactement cela, c'est le arbre structure. En utilisant une arborescence, vous pourrez représenter les différentes divisions pour chaque catégorie.

Arbres de décision

Comment remplir les nœuds d'un arbre ? C'est ici que arbres de décision mettre l'accent.

Premièrement, nous pouvons diviser les enregistrements par grossesse, après cela, nous pouvons les diviser en vivant dans des zones urbaines ou rurales. Notez que nous pourrions le faire dans un ordre différent, en divisant initialement par la région où vivent les femmes et ensuite par leur état de grossesse. De cela, nous pouvons voir que l'arbre a une hiérarchie inhérente. Outre l'organisation des informations, un arbre organise les informations de manière hiérarchique - l'ordre dans lequel les informations apparaissent est important et conduit à différents arbres en conséquence.

Ci-dessous, un exemple de l'arbre qui a été décrit :

Dans l'image de l'arbre, il y a 7 carrés, celui du haut qui représente le total de 100 femmes, ce carré du haut est relié aux deux carrés du bas, qui divisent les femmes en fonction de leur nombre de 78 non enceintes et 22 enceintes, et des deux carrés précédents, il y a quatre carrés ; deux reliées à chaque carré au-dessus qui divisent les femmes en fonction de leur zone, pour les non enceintes, 45 habitent en milieu urbain, 33 en milieu rural et pour les enceintes, 14 habitent en milieu rural et 8 en milieu urbain. Juste en regardant l'arbre, il est facile de comprendre ces divisions et de voir comment chaque "couche" est dérivée des précédentes, ces couches sont l'arbre niveaux, les niveaux décrivent profondeur de l'arbre :

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Observez dans l'image ci-dessus que le premier niveau d'arborescence est niveau 0 où il n'y a qu'un seul carré, suivi de niveau 1 où il y a deux carrés, et niveau 2 où il y a quatre carrés. C'est un profondeur 2 arbre.

Au niveau 0 se trouve le carré qui est à l'origine de l'arbre, le premier, appelé Noeud principal, cette racine a deux nœuds enfants au niveau 1, qui sont nœuds parents aux quatre nœuds du niveau 2. Voyez que les « carrés » que nous avons mentionnés jusqu'à présent sont en fait appelés nœuds; et que chaque nœud précédent est un parent des nœuds suivants, qui sont ses enfants. Les nœuds enfants de chaque niveau qui ont le même parent sont appelés frères et sœurs, comme on peut le voir dans l'image suivante :

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Dans l'image précédente, nous affichons également le niveau 1 comme étant le nœuds intérieurs, une fois qu'ils sont entre la racine et les derniers nœuds, qui sont les nœuds feuilles. Les nœuds foliaires sont la dernière partie d'un arbre, si nous devions dire à partir des 100 premières femmes, combien sont enceintes et vivent dans les zones rurales, nous pourrions le faire en regardant les feuilles. Ainsi, le nombre sur les feuilles répondrait à la première question de recherche.

S'il y avait de nouveaux enregistrements de femmes, et que l'arbre qui était auparavant utilisé pour les catégoriser, était maintenant utilisé pour décider si une femme pouvait ou non faire partie de la recherche, fonctionnerait-il toujours ? L'arbre utiliserait les mêmes critères, et une femme serait admissible à participer si elle est enceinte et vit dans une zone rurale.

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

En regardant l'image ci-dessus, on peut voir que les réponses aux questions de chaque nœud de l'arbre – « est-elle participante ? », « est-elle enceinte ? », « vit-elle en zone rurale ? »- sont oui, oui, et oui, donc il semble que l'arbre peut effectivement conduire à une décision, dans ce cas, que la femme puisse participer à la recherche.

Il s'agit de la essence d'arbres de décision, fait de manière manuelle. En utilisant Machine Learning, nous pouvons construire un modèle qui construit cet arbre automatiquement pour nous, de manière à maximiser la précision des décisions finales.

Remarque: il existe plusieurs types d'arbres en informatique, tels que les arbres binaires, les arbres généraux, les arbres AVL, les arbres évasés, les arbres rouges noirs, les arbres b, etc. Ici, nous nous concentrons sur une idée générale de ce qu'est un arbre de décision . Si cela dépend de la réponse d'un Oui or aucune question pour chaque nœud et donc chaque nœud a au plus deux enfants, lorsqu'il est trié de manière à ce que les nœuds "plus petits" soient à gauche, cela classe les arbres de décision comme arbres binaires.

Dans les exemples précédents, observez comment l'arbre pourrait soit classer de nouvelles données en tant que participant ou non participant, ou les questions pourraient également être changées en - "combien sont des participants?", "combien sont enceintes?", "combien vivent dans une zone rurale?" Quantité des participantes enceintes qui vivent en milieu rural.

Lorsque les données sont classifiées, cela signifie que l'arbre effectue une classification tâche, et lorsque la quantité de données est trouvée, l'arbre effectue une régression tâche. Cela signifie que l'arbre de décision peut être utilisé pour les deux tâches - classification et régression.

Maintenant que nous comprenons ce qu'est un arbre de décision, comment peut-il être utilisé et quelle nomenclature est utilisée pour le décrire, nous pouvons nous interroger sur ses limites.

Comprendre les forêts aléatoires

Qu'advient-il de la décision si un participant vit sur la division entre les zones urbaines et rurales ? L'arbre ajouterait-il cet enregistrement à rural ou urbain ? Il semble difficile d'intégrer ces données dans la structure que nous avons actuellement, car elle est assez claire.

De plus, que se passe-t-il si une femme qui vit sur un bateau participe à la recherche, cela sera-t-il considéré comme rural ou urbain ? De la même manière que le cas précédent, il s'agit d'un point de données difficile à classer compte tenu des options disponibles dans l'arborescence.

En réfléchissant un peu plus à l'exemple de l'arbre de décision, nous pouvons voir qu'il peut classer correctement les nouvelles données en considérant qu'elles suivent déjà un modèle que l'arbre a déjà - mais quand il y a des enregistrements qui diffèrent des données initiales qui ont défini l'arbre, le l'arborescence est trop rigide, rendant les enregistrements non classables.

Cela signifie que l'arbre de décision peut être strict et limité dans ses possibilités. Un arbre de décision idéal serait plus flexible et capable d'accueillir des données invisibles plus nuancées.

Solution: Tout comme "deux paires d'yeux voient mieux qu'une", deux modèles proposent généralement une réponse plus précise qu'une. Compte tenu de la diversité des représentations des connaissances (encodées dans l'arborescence), la rigidité des structures légèrement différentes entre plusieurs arbres similaires n'est plus aussi limitante, puisque les défauts d'un arbre peuvent être "compensés" par un autre. En combinant plusieurs arbres ensemble, nous obtenons un forêt.

Concernant la réponse à la question initiale, nous savons déjà qu'elle sera encodée dans les feuilles des arbres – mais qu'est-ce qui change lorsque nous avons plusieurs arbres au lieu d'un ?

Si les arbres sont combinés pour un classement, le résultat sera défini par la majorité des réponses, cela s'appelle vote à la majorité; et dans le cas d'une régression, le nombre donné par chaque arbre de la forêt sera en moyenne.

Apprentissage d'ensemble et ensembles modèles

Cette méthode est connue sous le nom apprentissage d'ensemble. Lors de l'utilisation de l'apprentissage d'ensemble, vous pouvez mélanger tous les algorithmes, tant que vous pouvez vous assurer que la sortie peut être analysée et combinée avec d'autres sorties (soit manuellement, soit à l'aide de bibliothèques existantes). En règle générale, vous regroupez plusieurs modèles du même type, tels que plusieurs arbres de décision, mais vous n'êtes pas limité à simplement joindre des ensembles de même type de modèle.

L'assemblage est un moyen pratiquement garanti de mieux généraliser un problème et d'obtenir une légère amélioration des performances. Dans certains cas, l'assemblage de modèles donne une significative augmentation du pouvoir prédictif, et parfois, juste légère. Cela dépend de l'ensemble de données sur lequel vous vous entraînez et évaluez, ainsi que des modèles eux-mêmes.

Rejoindre les arbres de décision donne significative les performances augmentent par rapport aux arbres individuels. Cette approche a été popularisée dans les communautés de recherche et d'apprentissage automatique appliqué, et était si courante que l'ensemble d'arbres de décision a été familièrement appelé un forêt, et le type commun de forêt qui était en cours de création (une forêt d'arbres de décision sur un sous-ensemble aléatoire d'entités) a popularisé le nom forêts aléatoires.

Compte tenu de l'utilisation à grande échelle, des bibliothèques comme Scikit-Learn ont implémenté des wrappers pour RandomForestRegressors et RandomForestClassifiers, construits au-dessus de leurs propres implémentations d'arbres de décision, pour permettre aux chercheurs d'éviter de construire leurs propres ensembles.

Plongeons dans des forêts aléatoires !

Comment fonctionne l'algorithme de forêt aléatoire ?

Voici les étapes de base impliquées lors de l'exécution de l'algorithme de forêt aléatoire :

  1. Choisissez un nombre d'enregistrements aléatoires, il peut s'agir de n'importe quel nombre, tel que 4, 20, 76, 150 ou même 2.000 XNUMX de l'ensemble de données (appelé N enregistrements). Le nombre dépendra de la largeur de l'ensemble de données, plus il est large, plus il est grand N peut être. C'est là que le aléatoire partie dans le nom de l'algorithme vient de !
  2. Construire un arbre de décision basé sur ces N enregistrements aléatoires ;
  3. Selon le nombre d'arbres définis pour l'algorithme, ou le nombre d'arbres dans la forêt, répétez les étapes 1 et 2. Cela génère plus d'arbres à partir d'ensembles d'enregistrements de données aléatoires ;
  4. Après l'étape 3, vient la dernière étape, qui consiste à prédire les résultats :
    • En cas de classement : chaque arbre de la forêt prédira la catégorie à laquelle appartient le nouvel enregistrement. Après cela, le nouveau record est attribué à la catégorie qui remporte le vote majoritaire.
    • En cas de régression : chaque arbre de la forêt prédit une valeur pour le nouvel enregistrement, et la valeur de prédiction finale sera calculée en prenant une moyenne de toutes les valeurs prédites par tous les arbres de la forêt.

Chaque arbre ajusté sur un sous-ensemble aléatoire de caractéristiques n'aura nécessairement aucune connaissance de certaines autres caractéristiques, ce qui est rectifié par l'assemblage, tout en maintenant le coût de calcul plus bas.

Conseils: Étant donné que Random Forest utilise les arbres de décision comme base, il est très utile de comprendre comment fonctionnent les arbres de décision et de s'entraîner avec eux individuellement pour construire une intuition sur leur structure. Lors de la composition de forêts aléatoires, vous définirez des valeurs telles que la profondeur maximale d'un arbre, le nombre minimum d'échantillons requis pour se trouver à un nœud feuille, les critères sur lesquels parier déterminer les divisions internes, etc. pour aider l'ensemble à mieux s'adapter à un nœud feuille. ensemble de données et généraliser à de nouveaux points. En pratique, vous utiliserez généralement Random Forests, Gradient Boosting ou Extreme Gradient Boosting ou d'autres méthodologies basées sur des arbres. Ainsi, avoir une bonne compréhension des hyperparamètres d'un arbre de décision unique vous aidera à construire une solide intuition pour régler les ensembles.

Avec une intuition sur le fonctionnement des arbres et une compréhension des forêts aléatoires, il ne reste plus qu'à s'entraîner à les construire, à les former et à les ajuster sur les données !

Construire et entraîner des modèles de forêts aléatoires avec Scikit-Learn

Il y avait une raison pour laquelle les exemples utilisés jusqu'à présent concernaient la grossesse, le lieu de vie et les femmes.

En 2020, des chercheurs du Bangladesh ont remarqué que la mortalité chez les femmes enceintes était encore très élevée, surtout si l'on considère celles qui vivent dans les zones rurales. Pour cette raison, ils ont utilisé un système de surveillance IOT pour analyser le risque pour la santé maternelle. Le système IOT a collecté des données auprès de différents hôpitaux, cliniques communautaires et centres de santé maternelle des zones rurales du Bangladesh.

Les données collectées ont ensuite été organisées dans un fichier de valeurs séparées par des virgules (csv) et téléchargées sur Référentiel d'apprentissage automatique de l'UCI.

Ce sont les données que nous utiliserons pour pratiquer et essayer de comprendre si une femme enceinte a un faible, moyenne or Élevée risque de mortalité.

Notes: vous pouvez télécharger le jeu de données ici.

Utilisation de la forêt aléatoire pour la classification

Puisque nous voulons savoir si la femme a un faible, moyenne or Élevée risque de mortalité, cela signifie que nous allons effectuer une classification en trois classes. Lorsqu'un problème comporte plus de deux classes, on l'appelle un multiclasse problème, par opposition à un binaire problème (où vous choisissez entre deux classes, généralement 0 ainsi que 1).

Dans ce premier exemple, nous allons implémenter un modèle de classification multiclasse avec un classificateur Random Forest et le Scikit-Learn de Python.

Nous suivrons les étapes habituelles d'apprentissage automatique pour résoudre ce problème, qui consistent à charger des bibliothèques, à lire les données, à consulter des statistiques récapitulatives et à créer des visualisations de données pour mieux le comprendre. Ensuite, le prétraitement et le fractionnement des données suivis de la génération, de la formation et de l'évaluation d'un modèle.

Importation de bibliothèques

Nous utiliserons Pandas pour lire les données, Seaborn et Matplotlib pour les visualiser, et NumPy pour les excellentes méthodes utilitaires :

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
Importation du jeu de données

Le code suivant importe le jeu de données et le charge dans un python DataFrame:

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")

Pour regarder les cinq premières lignes des données, nous exécutons la commande head() commander:

dataset.head()

Cela produit:

    Age SystolicBP  DiastolicBP BS      BodyTemp    HeartRate   RiskLevel
0   25  130         80          15.0    98.0        86          high risk
1   35  140         90          13.0    98.0        70          high risk
2   29  90          70          8.0     100.0       80          high risk
3   30  140         85          7.0     98.0        70          high risk
4   35  120         60          6.1     98.0        76          low risk

Ici, nous pouvons voir tous les attributs collectés au cours de la recherche.

  • Âge : âges en années.
  • TA systolique : valeur supérieure de la pression artérielle en mmHg, un attribut important pendant la grossesse.
  • PA diastolique : valeur inférieure de la pression artérielle en mmHg, un autre attribut important pendant la grossesse.
  • BS : niveaux de glucose dans le sang en termes de concentration molaire, mmol/L.
  • HeartRate : fréquence cardiaque au repos en battements par minute.
  • RiskLevel : niveau de risque pendant la grossesse.
  • BodyTemp : la température corporelle.

Maintenant que nous comprenons mieux ce qui est mesuré, nous pouvons examiner les types de données avec info():

dataset.info()

Cela se traduit par:


RangeIndex: 1014 entries, 0 to 1013
Data columns (total 7 columns):
 #   Column       Non-Null Count  Dtype  
---  ------       --------------  -----  
 0   Age          1014 non-null   int64  
 1   SystolicBP   1014 non-null   int64  
 2   DiastolicBP  1014 non-null   int64  
 3   BS           1014 non-null   float64
 4   BodyTemp     1014 non-null   float64
 5   HeartRate    1014 non-null   int64  
 6   RiskLevel    1014 non-null   object 
dtypes: float64(2), int64(4), object(1)
memory usage: 55.6+ KB

En regardant le RangeIndex ligne, nous pouvons voir qu'il y a 1014 enregistrements, et la colonne Non-Null Count informe que les données n'ont pas de valeurs manquantes. Cela signifie que nous n'aurons pas besoin de faire de traitement pour les données manquantes !

Dans le Dtype colonne, nous pouvons voir le type de chaque variable. Actuellement, float64 des colonnes telles BS ainsi que BodyTemp ont des valeurs numériques qui peuvent varier dans n'importe quelle plage, telles que 15.0, 15.51, 15.76, 17.28, ce qui les rend numériquement continue (vous pouvez toujours ajouter un 0 à un nombre à virgule flottante, à l'infini). En revanche, des variables telles que Age, SystolicBP, DiastolicBPet HeartRate sont du type int64, cela signifie que les nombres ne changent que par unité, comme 11, 12, 13, 14 - nous n'aurons pas une fréquence cardiaque de 77.78, c'est soit 77 ou 78 - ce sont numériquement discret valeurs. Et nous avons aussi RiskLevel avec une object type, cela indique généralement que la variable est un texte, et nous aurons probablement besoin de le transformer en un nombre. Étant donné que le niveau de risque augmente de faible à élevé, il y a un ordre implicite dans les catégories, cela indique qu'il s'agit d'un catégoriquement ordinal variable.

Notes: il est important de regarder le type de chaque donnée, et de voir si cela a du sens selon son contexte. Par exemple, cela n'a pas de sens d'avoir la moitié d'une unité de fréquence cardiaque, cela signifie donc que le type entier est adéquat pour une valeur discrète. Lorsque cela ne se produit pas, vous pouvez modifier le type de données avec Pandas' astype() propriété – df['column_name'].astype('type').

Après avoir examiné les types de données, nous pouvons utiliser describe() pour jeter un coup d'œil à certaines statistiques descriptives, telles que les valeurs moyennes de chaque colonne, l'écart type, les quantiles, les valeurs de données minimales et maximales :

dataset.describe().T 

Le code ci-dessus affiche :

            count   mean        std         min     25%     50%     75%     max
Age         1014.0  29.871795   13.474386   10.0    19.0    26.0    39.0    70.0
SystolicBP  1014.0  113.198225  18.403913   70.0    100.0   120.0   120.0   160.0
DiastolicBP 1014.0  76.460552   13.885796   49.0    65.0    80.0    90.0    100.0
BS          1014.0  8.725986    3.293532    6.0     6.9     7.5     8.0     19.0
BodyTemp    1014.0  98.665089   1.371384    98.0    98.0    98.0    98.0    103.0
HeartRate   1014.0  74.301775   8.088702    7.0     70.0    76.0    80.0    90.0
RiskLevel   1014.0  0.867850    0.807353    0.0     0.0     1.0     2.0     2.0

Notez que pour la plupart des colonnes, le signifier les valeurs sont loin des écart type (std) – cela indique que les données ne suivent pas nécessairement une distribution statistique bien comportée. Si c'était le cas, cela aurait aidé le modèle à prédire le risque. Ce qui peut être fait ici est de prétraiter les données pour les rendre plus représentatives comme s'il s'agissait de données de l'ensemble de la population mondiale, ou plus normalisée. Mais, un avantage lors de l'utilisation de modèles de forêts aléatoires pour classification, est que la structure arborescente inhérente peut bien traiter les données qui n'ont pas été normalisées, une fois qu'elle les divise par la valeur de chaque niveau d'arborescence pour chaque variable.

De plus, parce que nous utilisons des arbres et que la classe résultante sera obtenue en votant, nous ne comparons pas intrinsèquement entre différentes valeurs, seulement entre les mêmes types de valeurs, donc ajuster les caractéristiques à la même échelle n'est pas nécessaire dans ce cas . Cela signifie que le modèle de classification Random Forest est invariant d'échelle, et vous n'avez pas besoin d'effectuer de mise à l'échelle des fonctionnalités.

Dans ce cas, l'étape de prétraitement des données que nous pouvons entreprendre consiste à transformer le RiskLevel colonne en une colonne numérique.

Visualiser les données

Avant de transformer RiskLevel, visualisons également rapidement les données en examinant les combinaisons de points pour chaque paire d'entités avec un nuage de points et comment les points sont distribués en visualisant la courbe de l'histogramme. Pour ce faire, nous utiliserons Seaborn's pairplot() qui combine les deux parcelles. Il génère les deux tracés pour chaque combinaison de caractéristiques et affiche les points codés par couleur en fonction de leur niveau de risque avec le hue propriété:

g = sns.pairplot(dataset, hue='RiskLevel')
g.fig.suptitle("Scatterplot and histogram of pairs of variables color coded by risk level", 
               fontsize = 14, 
               y=1.05); 

Le code ci-dessus génère :

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Lorsque l'on regarde le tracé, la situation idéale serait d'avoir une séparation claire entre les courbes et les points. Comme nous pouvons le voir, les trois types de classes de risque sont pour la plupart mélangés, puisque les arbres tracent des lignes en interne lors de la délimitation des espaces entre les points, nous pouvons émettre l'hypothèse que plus d'arbres dans la forêt pourraient être en mesure de limiter plus d'espaces et de mieux classer les points.

Une fois l'analyse de données exploratoire de base effectuée, nous pouvons prétraiter RiskLevel colonne.

Prétraitement des données pour la classification

Certes, il n'y a que trois classes de RiskLevel dans nos données, et qu'aucune autre valeur n'a été ajoutée par erreur, nous pouvons utiliser unique() pour afficher les valeurs uniques de la colonne :

dataset['RiskLevel'].unique()

Cela produit:

array(['high risk', 'low risk', 'mid risk'], dtype=object)

Les classes sont vérifiées, maintenant l'étape suivante consiste à transformer chaque valeur en un nombre. Puisqu'il y a un ordre entre les classifications, nous pouvons utiliser les valeurs 0, 1 et 2 pour signifier faible, moyenne ainsi que Élevée des risques. Il existe de nombreuses façons de modifier les valeurs des colonnes, en suivant Python simple vaut mieux que complexe devise, nous utiliserons la .replace() méthode, et remplacez-les simplement par leurs représentations entières :

dataset['RiskLevel'] = dataset['RiskLevel'].replace('low risk', 0).replace('mid risk', 1).replace('high risk', 2)

Après avoir remplacé les valeurs, nous pouvons diviser les données en ce qui sera utilisé pour la formation du modèle, le Caractéristiques or X, et ce que nous voulons prédire, le qui or y:

y = dataset['RiskLevel']
X = dataset.drop(['RiskLevel'], axis=1)

Une fois que le X ainsi que y les ensembles sont prêts, nous pouvons utiliser Scikit-Learn train_test_split() méthode pour les diviser davantage en ensembles de train et de test :

from sklearn.model_selection import train_test_split

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

Conseils: n'oubliez pas d'utiliser une graine d'état aléatoire si vous voulez rendre le résultat reproductible. Nous avons utilisé une graine d'état aléatoire afin que vous puissiez reproduire les mêmes résultats que ceux du guide.

Ici, nous utilisons 20% des données pour les tests et 80% pour la formation.

Formation d'un RandomForestClassifier

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!

Ensembles mis en œuvre par Scikit-Learn sous le sklearn.ensemble module. Un ensemble d'arbres de décision utilisés pour la classification, dans lesquels un vote majoritaire est pris, est mis en œuvre comme RandomForestClassifier.

Ayant les ensembles d'entraînement et de test, nous pouvons importer le RandomForestClassifier classe et créer le modèle. Pour commencer, créons une forêt avec trois arbres, en définissant n_estimators paramètre à 3, et avec chaque arbre ayant trois niveaux, en réglant max_depthà 2:

from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier(n_estimators=3, 
                             max_depth=2,
                             random_state=SEED)

Remarque: La valeur par défaut pour n_estimators is 100. Cela renforce la puissance prédictive et la généralisation de l'ensemble, mais nous en créons un plus petit pour faciliter sa visualisation et son inspection. Avec seulement 3 arbres, nous pouvons les visualiser et les inspecter manuellement pour construire davantage notre intuition à la fois des arbres individuels et de leur co-dépendance. Il en va de même pour max_depth, lequel est None, ce qui signifie que les arbres peuvent devenir de plus en plus profonds pour s'adapter aux données selon les besoins.

Pour ajuster le modèle autour des données - nous appelons le fit() méthode, en passant dans les fonctionnalités de formation et les étiquettes :


rfc.fit(X_train, y_train)

y_pred = rfc.predict(X_test)

Nous pouvons maintenant comparer les étiquettes prédites aux étiquettes réelles pour évaluer les performances du modèle ! Avant d'évaluer le modèle, examinons l'ensemble.

Pour approfondir un peu le modèle, nous pouvons visualiser chacun des arbres et comment ils divisent les données. Cela peut être fait en utilisant le tree module intégré à Scikit-Learn, puis en boucle sur chacun des estimateurs de l'ensemble :


from sklearn import tree

features = X.columns.values 
classes = ['0', '1', '2'] 



for estimator in rfc.estimators_:
    print(estimator)
    plt.figure(figsize=(12,6))
    tree.plot_tree(estimator,
                   feature_names=features,
                   class_names=classes,
                   fontsize=8, 
                   filled=True, 
                   rounded=True)
    plt.show()

Le code ci-dessus affiche les arborescences :

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.
Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Remarquez comment les trois arbres sont différents. Le premier commence par le BS caractéristique, la seconde avec DiastolicBP, et le troisième avec BS encore. Bien que le troisième porte sur un nombre différent d'échantillons. Sur la branche de droite, les deux premiers arbres décident également d'utiliser Age au niveau de la feuille, tandis que le troisième arbre se termine par BS caractéristique. Avec seulement trois estimateurs, il est clair que la mise à l'échelle donne une représentation riche et diversifiée des connaissances qui peuvent être regroupées avec succès dans un modèle très précis.

Plus il y a d'arbres dans la forêt, plus le modèle peut être diversifié. Il y a un point de rendements décroissants, cependant, comme avec de nombreux arbres adaptés à un sous-ensemble aléatoire d'entités, il y aura pas mal d'arbres similaires qui n'offrent pas beaucoup de diversité dans l'ensemble, et qui commenceront à avoir trop de pouvoir de vote et fausser l'ensemble pour qu'il soit surajusté sur l'ensemble de données d'apprentissage, ce qui nuit à la généralisation à l'ensemble de validation.

Il y avait une hypothèse faite plus tôt sur le fait d'avoir plus d'arbres et comment cela pourrait améliorer les résultats du modèle. Examinons les résultats, générons un nouveau modèle et voyons si l'hypothèse tient !

Évaluation de RandomForestClassifier

Scikit-Learn facilite la création de lignes de base en fournissant un DummyClassifier, qui génère des prédictions sans utiliser les entités d'entrée (sorties totalement aléatoires). Si votre modèle est meilleur que le DummyClassifier, quelques l'apprentissage se fait ! Pour optimiser l'apprentissage, vous pouvez tester automatiquement divers hyperparamètres à l'aide d'un RandomizedSearchCV or GridSearchCV. En plus d'avoir une ligne de base, vous pouvez évaluer les performances de votre modèle à partir de plusieurs métriques.

Certaines mesures de classification traditionnelles qui peuvent être utilisées pour évaluer l'algorithme sont la précision, le rappel, le score f1, l'exactitude et la matrice de confusion. Voici une brève explication sur chacun d'eux :

  1. La précision: lorsque notre objectif est de comprendre quelles valeurs de prédiction correctes ont été considérées comme correctes par notre classifieur. La précision divisera ces vraies valeurs positives par les échantillons qui ont été prédits comme positifs ;

$$
précision = frac{texte{vrais positifs}}{texte{vrais positifs} + texte{faux positifs}}
$$

  1. Rappeler: généralement calculé avec précision pour comprendre combien de vrais positifs ont été identifiés par notre classificateur. Le rappel est calculé en divisant les vrais positifs par tout ce qui aurait dû être prédit comme positif.

$$
rappel = frac{texte{vrais positifs}}{texte{vrais positifs} + texte{faux négatifs}}
$$

  1. Score F1: est l'équilibré ou moyenne harmonique de précision et de rappel. La valeur la plus basse est 0 et la plus élevée est 1. Lorsque f1-score est égal à 1, cela signifie que toutes les classes ont été correctement prédites - c'est un score très difficile à obtenir avec des données réelles (des exceptions existent presque toujours).

$$
texte{f1-score} = 2* frac{texte{précision} * texte{rappel}}{texte{précision} + texte{rappel}}
$$

  1. Matrice de confusion: lorsque nous avons besoin de savoir pour combien d'échantillons nous avons eu raison ou tort chaque classe. Les valeurs qui étaient correctes et correctement prédites sont appelées vrais positifs, ceux qui ont été prédits comme positifs mais qui n'étaient pas positifs sont appelés faux positifs. La même nomenclature de vrais négatifs ainsi que faux négatifs est utilisé pour les valeurs négatives ;

  2. Précision: décrit le nombre de prédictions que notre classificateur a eues. La valeur de précision la plus basse est 0 et la plus élevée est 1. Cette valeur est généralement multipliée par 100 pour obtenir un pourcentage :

$$
précision = frac{text{nombre de prédictions correctes}}{text{nombre total de prédictions}}
$$

Remarque: Il est pratiquement impossible d'obtenir une précision de 100 % sur des données réelles auxquelles vous voudriez appliquer l'apprentissage automatique. Si vous voyez un classificateur de précision à 100 %, ou même un résultat proche de 100 %, soyez sceptique et effectuez une évaluation. Une cause fréquente de ces problèmes est la fuite de données (fuite d'une partie du test d'entraînement dans un ensemble de tests, directement ou indirectement). Il n'y a pas de consensus sur ce qu'est « une bonne précision », principalement parce que cela dépend de vos données – parfois, une précision de 70 % sera élevée ! Parfois, ce sera une très faible précision. D'une manière générale, plus de 70 % est suffisant pour de nombreux modèles, mais c'est au chercheur de domaine de le déterminer.

Vous pouvez exécuter le script suivant pour importer les bibliothèques nécessaires et consulter les résultats :

from sklearn.metrics import classification_report, confusion_matrix

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk)')

print(classification_report(y_test,y_pred))

La sortie ressemblera à ceci:

                precision    recall  f1-score   support

           0       0.53      0.89      0.66        80
           1       0.57      0.17      0.26        76
           2       0.74      0.72      0.73        47

    accuracy                           0.58       203
   macro avg       0.61      0.59      0.55       203
weighted avg       0.59      0.58      0.53       203

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Dans le rapport de classification, observez que le rappel est élevé, 0.89 pour la classe 0, la précision et le rappel sont élevés pour la classe 2, 0.74, 0.72 - et pour la classe 1, ils sont faibles, en particulier le rappel de 0.17 et une précision de 0.57 . La relation entre le rappel et la précision pour les trois classes individuellement est capturée dans le F1 score, qui est la moyenne harmonique entre le rappel et la précision – le modèle fait bien pour la classe 0, assez mauvais pour la classe 1 et correct pour la classe 2.

Le modèle a beaucoup de mal à identifier le cas à risque moyen.

La précision obtenue par notre classificateur de forêt aléatoire avec seulement 3 arbres est de 0.58 (58%) - cela signifie qu'il obtient un peu plus de la moitié des bons résultats. Il s'agit d'une faible précision, qui pourrait peut-être être améliorée en ajoutant plus d'arbres.

En examinant la matrice de confusion, nous pouvons voir que la plupart des erreurs surviennent lors de la classification de 52 enregistrements à risque moyen comme à faible risque, ce qui donne un aperçu supplémentaire du faible rappel de la classe 1. Il est biaisé pour classer les patients à risque moyen comme à faible risque. patients à risque.

Une autre chose qui peut être vérifiée pour générer encore plus d'informations est les caractéristiques les plus prises en compte par le classifieur lors de la prédiction. C'est une étape importante à franchir pour systèmes d'apprentissage automatique explicables, et aide à identifier et à atténuer les biais dans les modèles.

Pour le voir, nous pouvons accéder au feature_importances_ propriété du classificateur. Cela nous donnera une liste de pourcentages, afin que nous puissions également accéder à la feature_names_in_ propriété pour obtenir le nom de chaque fonctionnalité, les organiser dans un dataframe, les trier du plus haut au plus bas et tracer le résultat :


features_df = pd.DataFrame({'features': rfc.feature_names_in_, 'importances': rfc.feature_importances_ })


features_df_sorted = features_df.sort_values(by='importances', ascending=False)


g = sns.barplot(data=features_df_sorted, x='importances', y ='features', palette="rocket")
sns.despine(bottom = True, left = True)
g.set_title('Feature importances')
g.set(xlabel=None)
g.set(ylabel=None)
g.set(xticks=[])
for value in g.containers:
    g.bar_label(value, padding=2)

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Remarquez comment le classificateur considère principalement le sucre dans le sang, puis un peu de pression diastolique, de température corporelle et juste un peu d'âge pour prendre une décision, cela pourrait aussi avoir à voir avec le faible rappel de la classe 1, peut-être que les données de risque moyen ont à voir avec des caractéristiques qui ne sont pas pris en compte par le modèle. Vous pouvez essayer de jouer davantage avec les importances des fonctionnalités pour étudier cela et voir si les modifications apportées au modèle affectent les fonctionnalités utilisées, également s'il existe une relation significative entre certaines des fonctionnalités et les classes prédites.

Il est enfin temps de générer un nouveau modèle avec plus d'arbres pour voir comment cela affecte les résultats. Créons le rfc_ forêt avec 900 arbres, 8 niveaux et la même graine. Les résultats vont-ils s'améliorer ?

rfc_ = RandomForestClassifier(n_estimators=900, 
                             max_depth=7,
                             random_state=SEED)
rfc_.fit(X_train, y_train)
y_pred = rfc_.predict(X_test)

Calcul et affichage des métriques :

cm_ = confusion_matrix(y_test, y_pred)
sns.heatmap(cm_, annot=True, fmt='d').set_title('Maternal risks confusion matrix (0 = low risk, 1 = medium risk, 2 = high risk) for 900 trees with 8 levels')

print(classification_report(y_test,y_pred))

Cela produit:

                precision    recall  f1-score   support

           0       0.68      0.86      0.76        80
           1       0.75      0.58      0.65        76
           2       0.90      0.81      0.85        47

    accuracy                           0.74       203
   macro avg       0.78      0.75      0.75       203
weighted avg       0.76      0.74      0.74       203

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Cela montre comment l'ajout d'arbres supplémentaires et d'arbres plus spécialisés (niveaux supérieurs) a amélioré nos métriques. Nous avons toujours un faible rappel pour la classe 1, mais la précision est maintenant de 74 %. Le score F1 lors de la classification des cas à haut risque est de 0.85, ce qui signifie que les cas à haut risque sont désormais plus facilement identifiés par rapport à 0.73 dans le modèle précédent !

Dans un projet au jour le jour, il peut être plus important d'identifier les cas à haut risque, par exemple avec une métrique similaire à la précision, également connue sous le nom de Un niveau de sensibilité élevée dans les statistiques. Essayez de modifier certains paramètres du modèle et observez les résultats.

Jusqu'à présent, nous avons obtenu une compréhension globale de la façon dont la forêt aléatoire peut être utilisée pour classer les données - dans la section suivante, nous pouvons utiliser le même ensemble de données d'une manière différente pour voir comment le même modèle prédit les valeurs avec régression.

Utilisation de forêts aléatoires pour la régression

Dans cette section, nous étudierons comment un algorithme Random Forest peut être utilisé pour résoudre des problèmes de régression à l'aide de Scikit-Learn. Les étapes suivies pour mettre en œuvre cet algorithme sont presque identiques aux étapes effectuées pour la classification, outre le type de modèle et le type de données prédites - qui seront désormais des valeurs continues - il n'y a qu'une seule différence dans la préparation des données.

Puisque la régression est effectuée pour valeurs numériques – choisissons une valeur numérique dans l'ensemble de données. Nous avons vu que la glycémie était importante dans la classification, elle devrait donc être prévisible en fonction d'autres caractéristiques (puisque si elle est en corrélation avec une caractéristique, cette caractéristique est également en corrélation avec elle).

Après ce que nous avons fait pour la classification, importons d'abord les bibliothèques et le même jeu de données. Si vous l'avez déjà fait pour le modèle de classification, vous pouvez ignorer cette partie et passer directement à la préparation des données pour la formation.

Importation de bibliothèques et de données
import pandas as pd
import numpy as np
import maplotlib.pyplot as plt
import seaborn as sns

dataset = pd.read_csv("../../datasets/random-forest/maternal_health_risk.csv")
Prétraitement des données pour la régression

Il s'agit d'une tâche de régression, donc au lieu de prédire les classes, nous pouvons prédire l'une des colonnes numériques de l'ensemble de données. Dans cet exemple, le BS colonne sera prédite. Cela signifie que le y les données contiendront données sur la glycémieet X les données contiendront toutes les caractéristiques en plus de la glycémie. Après avoir séparé le X ainsi que y données, nous pouvons diviser les ensembles d'entraînement et de test :

from sklearn.model_selection import train_test_split

SEED = 42

y = dataset['BS']
X = dataset.drop(['BS'], axis=1) 

X_train, X_test, y_train, y_test = train_test_split(X, y, 
                                                    test_size=0.2, 
                                                    random_state=SEED)
Formation d'un RandomForestRegressor

Maintenant que nous avons mis à l'échelle notre ensemble de données, il est temps d'entraîner notre algorithme pour résoudre ce problème de régression, pour le modifier un peu - nous allons créer un modèle avec 20 arbres dans la forêt et chacun avec 4 niveaux. Pour ce faire, vous pouvez exécuter le code suivant :

from sklearn.ensemble import RandomForestRegressor

rfr = RandomForestRegressor(n_estimators=20, 
                            max_depth=3, 
                            random_state=SEED)

rfr.fit(X_train, y_train)
y_pred = rfr.predict(X_test)

Vous pouvez trouver des détails pour tous les paramètres de RandomForestRegressor dans la documentation officielle.

Étant donné que tracer et examiner 20 arbres nécessiterait du temps et du dévouement, nous pouvons tracer uniquement le premier pour voir en quoi il diffère de l'arbre de classification :

from sklearn import tree

features = X.columns

first_tree = rfr.estimators_[0]

plt.figure(figsize=(15,6))
tree.plot_tree(first_tree,
               feature_names=features,
               fontsize=8, 
               filled=True, 
               rounded=True);

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Notez que l'arbre de régression a déjà une valeur affectée aux données qui tombent sur chaque nœud. Ce sont les valeurs qui seront moyennées lors de la combinaison des 20 arbres. Suite à ce que nous avons fait avec la classification, vous pouvez également tracer les importances des caractéristiques pour voir quelles variables le modèle de régression prend davantage en considération lors du calcul des valeurs.

Il est temps de passer à la dernière et dernière étape de la résolution d'un problème d'apprentissage automatique et d'évaluer les performances de l'algorithme !

Évaluation d'un RandomForestRegressor

Pour les problèmes de régression, les métriques utilisées pour évaluer un algorithme sont l'erreur absolue moyenne (MAE), l'erreur quadratique moyenne (MSE) et l'erreur quadratique moyenne (RMSE).

  1. Erreur absolue moyenne (MAE): lorsque nous soustrayons les valeurs prédites des valeurs réelles, obtenant les erreurs, additionnons les valeurs absolues de ces erreurs et obtenons leur moyenne. Cette métrique donne une idée de l'erreur globale pour chaque prédiction du modèle, plus elle est petite (plus proche de 0) mieux c'est.

$$
mae = (frac{1}{n})sum_{i=1}^{n}gauche | Réel – Droit prévu |
$$

Remarque: Vous pouvez également rencontrer le y ainsi que ŷ notation dans les équations. La y fait référence aux valeurs réelles et aux ŷ aux valeurs prédites.

  1. Erreur quadratique moyenne (MSE): elle est similaire à la métrique MAE, mais elle met au carré les valeurs absolues des erreurs. De plus, comme pour MAE, plus il est petit ou proche de 0, mieux c'est. La valeur MSE est mise au carré afin de rendre les erreurs importantes encore plus importantes. Une chose à laquelle il faut prêter une attention particulière, c'est qu'il s'agit généralement d'une mesure difficile à interpréter en raison de la taille de ses valeurs et du fait qu'elles ne sont pas dans la même échelle de données.

$$
mse = sum_{i=1}^{D}(Réel - Prédit)^2
$$

  1. Erreur quadratique moyenne (RMSE): essaie de résoudre le problème d'interprétation soulevé avec l'EQM en obtenant la racine carrée de sa valeur finale, afin de la redimensionner aux mêmes unités de données. Il est plus facile à interpréter et bon lorsque nous devons afficher ou montrer la valeur réelle des données avec l'erreur. Il montre à quel point les données peuvent varier, donc, si nous avons un RMSE de 4.35, notre modèle peut faire une erreur soit parce qu'il a ajouté 4.35 à la valeur réelle, soit parce qu'il a besoin de 4.35 pour arriver à la valeur réelle. Plus on se rapproche de 0, mieux c'est aussi.

$$
rmse = sqrt{ sum_{i=1}^{D}(Réel - Prédit)^2}
$$

Nous pouvons utiliser n'importe laquelle de ces trois mesures pour comparer modèles (si nous devons en choisir un). Nous pouvons également comparer le même modèle de régression avec différentes valeurs d'argument ou avec différentes données, puis considérer les métriques d'évaluation. Ceci est connu comme réglage hyperparamètre – régler les hyperparamètres qui influencent un algorithme d'apprentissage et observer les résultats.

Lors du choix entre les modèles, ceux qui présentent les plus petites erreurs sont généralement plus performants. Lors de la surveillance des modèles, si les métriques se détérioraient, une version précédente du modèle était meilleure, ou il y avait une modification significative des données pour que le modèle fonctionne moins bien qu'il ne le faisait.

Vous pouvez utiliser le code suivant pour trouver ces valeurs :

from sklearn.metrics import mean_absolute_error, mean_squared_error

print('Mean Absolute Error:', mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(mean_squared_error(y_test, y_pred)))

La sortie doit être:

Mean Absolute Error: 1.127893702896059
Mean Squared Error: 3.0802988503933326
Root Mean Squared Error: 1.755078018320933

Avec 20 arbres, l'erreur quadratique moyenne est de 1.75, ce qui est faible, mais même ainsi - en augmentant le nombre d'arbres et en expérimentant avec les autres paramètres, cette erreur pourrait probablement devenir encore plus petite.

Avantages de l'utilisation de la forêt aléatoire

Comme pour tout algorithme, il y a des avantages et des inconvénients à l'utiliser. Dans les deux sections suivantes, nous examinerons les avantages et les inconvénients de l'utilisation d'une forêt aléatoire pour la classification et la régression.

  1. L'algorithme de forêt aléatoire n'est pas biaisé, car il existe plusieurs arbres et chaque arbre est formé sur un sous-ensemble aléatoire de données. Fondamentalement, l'algorithme de forêt aléatoire repose sur le pouvoir de « la foule » ; par conséquent, le degré global de biais de l'algorithme est réduit.
  2. Cet algorithme est très stable. Même si un nouveau point de données est introduit dans l'ensemble de données, l'algorithme global n'est pas beaucoup affecté puisque de nouvelles données peuvent avoir un impact sur un arbre, mais il est très difficile pour lui d'avoir un impact sur tous les arbres.
  3. L'algorithme de forêt aléatoire fonctionne bien lorsque vous avez à la fois des caractéristiques catégorielles et numériques.
  4. L'algorithme de forêt aléatoire fonctionne également bien lorsque les données ont des valeurs manquantes ou qu'elles n'ont pas été mises à l'échelle.

Inconvénients de l'utilisation de la forêt aléatoire

  1. Le principal inconvénient des forêts aléatoires réside dans leur complexité. Ils nécessitent beaucoup plus de ressources de calcul, en raison du grand nombre d'arbres de décision réunis, lors de l'entraînement de grands ensembles. Cependant, avec du matériel moderne, entraîner même une grande forêt aléatoire ne prend pas beaucoup de temps.

Aller plus loin - Projet de bout en bout tenu dans la main

Votre nature curieuse vous donne envie d'aller plus loin ? Nous vous recommandons de consulter notre Projet guidé: "Prévision pratique du prix des maisons - Apprentissage automatique en Python".

Guide définitif de l'algorithme de forêt aléatoire avec Python et Scikit-Learn PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Dans ce projet guidé, vous apprendrez à créer de puissants modèles d'apprentissage automatique traditionnels ainsi que des modèles d'apprentissage en profondeur, à utiliser Ensemble Learning et à former des méta-apprenants pour prédire les prix de l'immobilier à partir d'un ensemble de modèles Scikit-Learn et Keras.

À l'aide de Keras, l'API d'apprentissage en profondeur construite sur Tensorflow, nous allons expérimenter des architectures, créer un ensemble de modèles empilés et former un méta-apprenant réseau de neurones (modèle de niveau 1) pour déterminer le prix d'une maison.

L'apprentissage en profondeur est incroyable - mais avant d'y recourir, il est conseillé d'essayer également de résoudre le problème avec des techniques plus simples, comme avec apprentissage superficiel algorithmes. Notre performance de base sera basée sur un Régression forestière aléatoire algorithme. De plus, nous explorerons la création d'ensembles de modèles via Scikit-Learn via des techniques telles que ensachage ainsi que vote.

Il s'agit d'un projet de bout en bout, et comme tous les projets d'apprentissage automatique, nous commencerons par - avec L'analyse exploratoire des données, Suivie par Pré-traitement des données et enfin Bâtiment peu profond ainsi que Modèles d'apprentissage en profondeur pour correspondre aux données que nous avons explorées et nettoyées précédemment.

Horodatage:

Plus de Stackabuse