Cette fois, je résumerai la théorie des arbres de décision.
Je vous serais reconnaissant si vous pouviez vous entendre avec moi.
Tout d'abord, résumons la théorie des arbres 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
.
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.
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.
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.
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.
Exprimons l'impureté à l'aide d'une formule mathématique. Considérez la figure suivante.
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.
\frac{1}{N_m} \sum_{x_i\in R_m}^{}I(y_i \neq k(m)) = 1-\hat{p}_{mk}
1 - \sum_{k=1}^{K}\hat{p}_{mk}
-\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.
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é.
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.
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.
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()
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')
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()
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.
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()
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')
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()
Comme vous pouvez le voir sur l'illustration, ce n'est pas très correct.
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)
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)
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.
C'est tout pour cette fois.
Merci d'être resté avec nous jusqu'à présent.