[Python] J'ai expliqué en détail la théorie et la mise en œuvre de l'arbre de décision

introduction

Cette fois, je résumerai la théorie des arbres de décision.

Je vous serais reconnaissant si vous pouviez vous entendre avec moi.

Théorie

Tout d'abord, résumons la théorie des arbres de décision.

Aperçu de l'arbre de décision

La visualisation de l'arbre de décision est la suivante.

Cette fois, j'ai visualisé la classification par jeu de données iris en utilisant export_graphviz de scikit-learn. image.png

Un arbre de décision est un algorithme qui crée un modèle de classification ou de régression de données en divisant les données selon certaines conditions, comme indiqué dans l'image ci-dessus. L'arbre de classification pour la classification et l'arbre de retour pour la régression sont appelés collectivement l'arbre de décision.

Comme il s'agit d'un algorithme assez simple, il a tendance à être moins précis que d'autres algorithmes complexes.

Cependant, l'interprétabilité du modèle est très élevée.

C'est ce qu'on appelle un arbre de décision car le modèle ressemble à un arbre comme le montre la figure ci-dessus.

Les algorithmes typiques incluent "CART" et "C5.0".

Veuillez vous référer à l'article ici pour l'algorithme.

Ici, nous traiterons de l'algorithme CART qui répète la classification de Niclas.

À propos des critères de l'arbre de décision

Jusqu'à présent, je pense que vous avez un aperçu approximatif de l'arbre décisionnel.

Ici, nous allons considérer les critères de ramification des arbres classés et des arbres de retour.

Critères de l'arbre de classification

Maintenant, réfléchissons aux critères de branchement de l'arbre de classification.

Pour écrire à partir de la conclusion, la classification détermine la quantité de caractéristique et le seuil en fonction du critère de division de sorte que «l'impureté» soit minimisée.

«Impureté» est une valeur numérique du nombre de classes mélangées, et est exprimée en utilisant le «taux de mauvaise classification», «l'indice de Gini» et «l'erreur d'entropie croisée». Lorsqu'il y a une classe de sites d'observation sur un nœud, la pureté est de 0.

Critères pour l'arbre de retour

L'arbre de régression définit une fonction de coût représentée par l'erreur quadratique moyenne et sélectionne les caractéristiques et les seuils de sorte que la somme pondérée de la fonction de coût soit minimisée.

À propos des formules

Arbre de classification

Exprimons l'impureté à l'aide d'une formule mathématique. Considérez la figure suivante. image.png

Le rapport des valeurs observées de la classe k dans la région $ R_m $ avec $ N_m $ valeurs observées est défini comme suit.

\hat{p}_{mk} = \frac{1}{N_m} \sum_{x_i\in R_m}^{}I(y_i = k)

Faites attention à la troisième rangée à partir du haut de la figure. m représente le numéro d'aire, m = 1 représente l'aire de «gini = 0,168» et m = 2 représente l'aire de «gini = 0,043». k représente l'étiquette de classe, et cette fois, il est défini comme classe 1, classe 2 et classe 3 à gauche de la partie «valeur».

Il semble difficile de le formuler, mais le calcul proprement dit est le suivant.

\hat{p}_{11} = \frac{0}{54} \quad \hat{p}_{12} = \frac{49}{54}  \quad \hat{p}_{13} = \frac{5}{54} 

Avez-vous compris le sens de la formule?

En utilisant ce $ \ hat {p} $, l'impureté est exprimée par les trois fonctions suivantes.

Taux d'erreurs de classification

\frac{1}{N_m} \sum_{x_i\in R_m}^{}I(y_i \neq k(m)) = 1-\hat{p}_{mk}

Index de Gini

1 - \sum_{k=1}^{K}\hat{p}_{mk}

Erreur d'entropie croisée

-\sum_{k=1}^{K}\hat{p}_{mk}log\hat{p}_{mk}

La fonction impure utilisée en standard dans sklearn est l'indice de Gini, alors calculons en fait l'indice de Gini.

image.png

Calculez la pureté de la troisième étape à l'aide de l'indice de Gini.

L'indice de Gini du nœud avec «gini = 0,168» à gauche est le suivant.

1 - (\frac{0}{54})^2 - (\frac{49}{54})^2 - (\frac{5}{54})^2 = 0.168

Naturellement, la réponse est 0,168. La formule ci-dessus est la formule que sklearn utilise en interne. Calculons également le nœud de droite avec gini = 0.043.

1 - (\frac{0}{46})^2 - (\frac{1}{46})^2 - (\frac{45}{46})^2 = 0.043

Cela correspondait également. Calculons maintenant l'impureté globale en pondérant chacun d'eux avec les données. Cela devient la formule suivante.

\frac{54}{100} ×0.168 + \frac{46}{100} ×0.043 = 0.111

Avec cela, la pureté totale peut être dérivée. L'arbre de décision construit un modèle en sélectionnant des caractéristiques et des seuils qui réduisent cette impureté.

Arbre de retour

Dans l'arborescence de régression, définissez la fonction de coût comme suit.

\hat{c}_m = \frac{1}{N_m}\sum_{x_i \in R_m}^{}y_i\\
Q_m(T) = \frac{1}{N_m} \sum_{x_i \in R_m}(y_i - \hat{c}_m)^2

La fonction de coût est l'erreur quadratique moyenne car $ \ hat {c} _m $ représente la moyenne des observations contenues dans ce nœud.

Comme cette fonction de coût est calculée pour chaque nœud, définissez les caractéristiques et les seuils de sorte que la somme pondérée de la fonction de coût soit minimisée.

la mise en oeuvre

A présent, vous devriez avoir compris la théorie des arbres de classification et des arbres de retour.

Maintenant, implémentons l'arbre de décision.

Implémentation de l'arbre de classification

Nous implémentons maintenant un arbre de classification.

Commencez par créer les données à classer.

from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from matplotlib.colors import ListedColormap
import graphviz

moons = make_moons(n_samples=300, noise=0.2, random_state=0)
X = moons[0]
Y = moons[1]
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0, stratify=Y)

plt.figure(figsize=(12, 8))
mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.show()

image.png

Nous allons créer un modèle pour classer ces données.

Ci-dessous le code.

clf_model = DecisionTreeClassifier(max_depth=3)
clf_model.fit(X_train, Y_train)
print(clf_model.score(X_test, Y_test))

0.8933333333333333

La précision était raisonnable.

Visualisons le modèle de cet arbre de classification. Ci-dessous le code.

dot_data = export_graphviz(clf_model)
graph = graphviz.Source(dot_data)
graph.render('moon-tree', format='png')

image.png

Pour la visualisation à l'aide de graphviz, veuillez vous reporter à l'article ici.

Comme vous pouvez le voir, l'arbre de décision est très interprétable dans le modèle. Dans ce modèle, max_depth = 3 est défini, donc le modèle a une profondeur de 3.

Visualisons le modèle après classification. Ci-dessous le code.

plt.figure(figsize=(12, 8))
_x1 = np.linspace(X[:, 0].min() - 0.5, X[:, 0].max() + 0.5, 100)
_x2 = np.linspace(X[:, 1].min() - 0.5, X[:, 1].max() + 0.5, 100)
x1, x2 = np.meshgrid(_x1, _x2)
X_stack = np.hstack((x1.ravel().reshape(-1, 1), x2.ravel().reshape(-1, 1)))
y_pred = clf_model.predict(X_stack).reshape(x1.shape)
custom_cmap = ListedColormap(['mediumblue', 'orangered'])
plt.contourf(x1, x2, y_pred, alpha=0.3, cmap=custom_cmap)
mglearn.discrete_scatter(X[:, 0], X[:, 1], Y)
plt.show()

image.png

Veuillez vous référer à l'article ici pour savoir comment changer la couleur à l'aide de points de grille.

_x1 et _x2 spécifient la zone des points de la grille dans la direction de l'axe x et dans la direction de l'axe y, etx1, x2 = np.meshgrid (_x1, _x2)crée les points de la grille.

La grille unidimensionnelle 100 × 100 pointe sur la partie de X_stack = np.hstack ((x1.ravel (). Reshape (-1, 1), x2.ravel (). Reshape (-1, 1))) Après avoir changé en tableau, il est converti en un tableau bidimensionnel de 10000 x 1, puis combiné horizontalement pour le convertir en données de 10000 x 2.

Dans la partie de y_pred = clf_model.predict (X_stack) .reshape (x1.shape), les données 10000 × 2 sont converties en données 0 et 1, et elles sont converties en données 100 × 100. Un côté de la ligne qui sépare les données est 0 et l'autre est 1.

Tracez des lignes de contour à plt.contourf (x1, x2, y_pred, alpha = 0.3, cmap = custom_cmap). La couleur est spécifiée par cmap = custom_cmap.

C'est la fin de la mise en œuvre de l'arbre de classification.

Implémentation de l'arbre de retour

Maintenant, implémentons l'arborescence de retour.

Préparons les données et dessinons-les.

import mglearn
from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import export_graphviz
import graphviz

X, Y = mglearn.datasets.make_wave(n_samples=200)

plt.figure(figsize=(12, 8))
plt.plot(X, Y, 'bo', ms=15)
plt.show()

image.png

Les données sont comme ça. Créons maintenant un modèle.

tree_reg_model = DecisionTreeRegressor(max_depth=3)
tree_reg_model.fit(X, Y)
print(tree_reg_model.score(X, Y))

0.7755211625482443

Vous pouvez afficher $ R ^ 2 $ avec score.

score(self, X, y[, sample_weight]) Returns the coefficient of determination R^2 of the prediction.

La précision n'est pas très bonne.

Visualisons le modèle avec le code suivant.

dot_data = export_graphviz(tree_reg_model)
graph = graphviz.Source(dot_data)
graph.render('wave-tree', format='png')

image.png

Comme vous pouvez le voir, l'arbre de retour (ainsi que l'arbre de décision) a une très bonne interprétabilité du modèle.

Illustrons maintenant la ligne de régression avec le code suivant.

X1 = np.linspace(X.min() - 1, X.max() + 1, 1000).reshape(-1, 1)
y_pred = tree_reg_model.predict(X1)
plt.xlabel('x', fontsize=10)
plt.ylabel('y', fontsize=10, rotation=-0)
plt.plot(X, Y, 'bo', ms=5)
plt.plot(X1, y_pred, 'r-', linewidth=3)
plt.show()

image.png

Comme vous pouvez le voir sur l'illustration, ce n'est pas très correct.

Mis en œuvre sans spécifier de profondeur

Maintenant, implémentons-le sans implémenter de profondeur.

C'est la même chose sauf que vous ne spécifiez pas la profondeur, alors mettons les mêmes étapes ensemble dans une fonction.

import mglearn
from sklearn.tree import DecisionTreeRegressor
import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import export_graphviz
import graphviz

X, Y = mglearn.datasets.make_wave(n_samples=200)

tree_reg_model_2 = DecisionTreeRegressor()

tree_reg_model_2.fit(X, Y)

print(tree_reg_model_2.score(X, Y))

1.0

$ R ^ 2 $ vaut maintenant 1. De quel genre de modèle s'agit-il? Illustrons la branche ci-dessous.

def graph_export(model):
    dot_data = export_graphviz(model)
    graph = graphviz.Source(dot_data)
    graph.render('test', format='png')

graph_export(tree_reg_model_2)

image.png

C'était une branche terrifiante. Je ne peux plus lire comment ça se ramifie.

Illustrons le modèle avec le code suivant.

def plot_regression_predictions(tree_reg, x, y):
    x1 = np.linspace(x.min() - 1, x.max() + 1, 500).reshape(-1, 1)
    y_pred = tree_reg.predict(x1)
    plt.xlabel('x', fontsize=10)
    plt.ylabel('y', fontsize=10, rotation=-0)
    plt.plot(x, y, 'bo', ms=5)
    plt.plot(x1, y_pred, 'r-', linewidth=1)
    plt.show()


plot_regression_predictions(tree_reg_model_2, X, Y)

image.png

Comme vous pouvez le voir sur la figure ci-dessus, il s'agit clairement d'un surapprentissage.

Cela rend impossible la prédiction des données inconnues, vous pouvez donc comprendre l'importance de définir la profondeur de l'arbre de manière appropriée.

À la fin

C'est tout pour cette fois.

Merci d'être resté avec nous jusqu'à présent.

Recommended Posts

[Python] J'ai expliqué en détail la théorie et la mise en œuvre de l'arbre de décision
[Python] J'ai expliqué en détail la théorie et la mise en œuvre de la régression logistique
[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
J'ai vérifié les versions de Blender et Python
Créez un environnement python pour apprendre la théorie et la mise en œuvre de l'apprentissage profond
Visualisez les résultats des arbres de décision réalisés avec Python scikit-learn
Je veux connaître la nature de Python et pip
L'histoire de Python et l'histoire de NaN
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
[Introduction à Python] J'ai comparé les conventions de nommage de C # et Python.
Vérification de la théorie selon laquelle "Python et Swift sont assez similaires"
Le modèle de projet Python auquel je pense.
J'ai essayé de vérifier et d'analyser l'accélération de Python par Cython
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
J'ai lu l'implémentation de range (Objects / rangeobject.c)
Résumé des différences entre PHP et Python
La réponse de "1/2" est différente entre python2 et 3
Pourquoi l'implémentation Python d'ISUCON 5 a utilisé Bottle
Comparez la vitesse d'ajout et de carte Python
Implémentation de l'arbre TRIE avec Python et LOUDS
J'ai touché certaines des nouvelles fonctionnalités de Python 3.8 ①
Résumé relatif aux E / S de python et fortran
J'ai lu et implémenté les variantes de UKR
Prise en compte des forces et faiblesses de Python
Explication de la distance d'édition et de l'implémentation en Python
J'ai comparé la vitesse de l'écho du framework web en langage go et du flask du framework web python
J'ai comparé la vitesse des expressions régulières en Ruby, Python et Perl (version 2013)
[Python] Comparaison de la théorie de l'analyse des composants principaux et de l'implémentation par Python (PCA, Kernel PCA, 2DPCA)
[Recette du formateur] J'ai touché le flacon du framework Python.
L'histoire de Python sans opérateurs d'incrémentation et de décrémentation.
Le processus d'installation d'Atom et de l'exécution de Python
Construisez un serveur API pour vérifier le fonctionnement de l'implémentation frontale avec python3 et Flask
Python - Explication et résumé de l'utilisation des 24 meilleurs packages
Python pratique 100 coups J'ai essayé de visualiser l'arbre de décision du chapitre 5 en utilisant graphviz
J'ai suivi la mise en place de la commande du (première moitié)
J'ai essayé d'automatiser la mise à jour de l'article du blog Livedoor avec Python et sélénium.
Visualisez la gamme d'insertions internes et externes avec python
Implémentation python de la classe de régression linéaire bayésienne
Référence et modification de la limite supérieure récursive Python
J'ai comparé la vitesse de la référence du python dans la liste et la référence de l'inclusion du dictionnaire faite à partir de la liste dans.
J'ai vérifié le système d'exploitation et le shell par défaut de docker-machine
J'ai suivi la mise en place de la commande du (seconde moitié)
J'ai touché Bergeronnette (3). Enquête et mise en place de messages pop-up.
Un mémorandum sur la mise en œuvre des recommandations en Python
J'ai essayé de comparer la vitesse de traitement avec dplyr de R et pandas de Python
J'ai essayé de résumer les opérations de chaîne de Python
J'ai considéré la méthode d'apprentissage automatique et son langage d'implémentation à partir des informations de balise de Qiita
Implémentation Python du mode de fusion CSS3 et discussion sur l'espace colorimétrique
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
Une implémentation Python simple de la méthode k-voisinage (k-NN)
[Python] Fonctionnalisation de la formule de Heron et calcul de la surface maximale
J'ai écrit la grammaire de base de Python dans Jupyter Lab
J'ai évalué la stratégie de négociation du système boursier avec Python.
[Python] J'ai installé le jeu depuis pip et j'ai essayé de jouer