[PYTHON] Comprendre l'arbre de décision et classer les documents

introduction

Cette fois, j'ai résumé l'arbre de décision de l'algorithme d'apprentissage automatique. Afin de comprendre le système de développement de l'arbre de décision tel que Random Forest et XGBoost, je voudrais bien comprendre les bases.

référence

Pour comprendre l'arbre de décision, je me suis référé à ce qui suit.

Arbre de décision

Aperçu de l'arbre de décision

** L'arbre de décision est un algorithme qui recherche la «feuille» qui correspond le mieux à la condition en traçant la branche selon la condition à partir de la «racine». ** Créez une expression conditionnelle composée de variables explicatives en tant que nœud basé sur les données d'apprentissage, et créez automatiquement un modèle qui peut dériver le résultat de la prédiction dans la partie "feuille". Il peut gérer à la fois les problèmes de classification et les problèmes de régression, et ils sont appelés respectivement ** arbres de régression ** et ** arbres de classification **.

Les avantages et les inconvénients sont les suivants, mais je pense que l'avantage de ** facile à interpréter ** est la raison pour laquelle on utilise le plus l'arbre de décision.

mérite

--Facile à interpréter (visualisez clairement ce qui est jugé comme une quantité de caractéristiques)

Démérite

――Ce n'est pas une méthode avec des performances de classification élevées

Image de l'arbre de décision

Entraînons facilement l'algorithme d'arbre décisif pour le jeu de données iris de sklearn et dessinons l'arbre décisif.

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()

X = iris.data[:,2:]
y = iris.target

tree_clf = DecisionTreeClassifier(max_depth=2, random_state=42)
tree_clf.fit(X, y)

from graphviz import Source
from sklearn.tree import export_graphviz

export_graphviz(
        tree_clf,
        out_file=os.path.join("iris_tree.dot"),
        feature_names=iris.feature_names[2:],
        class_names=iris.target_names,
        rounded=True,
        filled=True
    )

Ce qui suit est exécuté sur la ligne de commande (pour convertir le fichier dot en png)

$ dot -Tpng iris_tree.dot -o iris_tree.png

Ensuite, l'arbre de décision suivant peut être généré. Il se branche selon que la condition est remplie (Vrai ou Faux), et les nœuds colorés sont utilisés comme «feuilles» pour dériver le résultat final de la prédiction.

iris_tree.png

Apprentissage et impureté des arbres de décision

Il y a ** impureté ** comme index pour voir si chaque nœud de l'arbre de décision est capable de créer une branche conditionnelle avec succès. De plus, il existe deux méthodes pour mesurer l '** impureté **: ** la pureté GINI ** et ** l'entropie **.

Impuretés GINI

En supposant que $ n $ est le nombre de classes contenues dans les données et que $ p_ {i} $ est la probabilité que les données soient de la classe $ i $, l'impureté de Gini peut être exprimée par la formule suivante.


Gini(p) = \sum_{i=1}^{n} p_{i}(1-p_{i}) = 1-\sum_{i=1}^{n} p_{i}^2

Il est difficile de comprendre s'il ne s'agit que d'une formule, alors regardons un exemple concret. Encore une fois, vérifiez la partie noeud vert de l'arbre de décision illustré précédemment. La valeur de ** valeurs ** ici indique combien de données peuvent être classées dans chaque classe de cette branche conditionnelle, et la valeur de ** classe ** détermine cette classification au moment de cette branche conditionnelle. , Représente cela.

iris_tree.png

Si vous vérifiez les * valeurs * du nœud vert, il s'agit de [0, 49, 5], ce qui signifie que 0 donnée est définie sur Setosa, 49 données sont définies sur Versicle et 5 données sont définies sur Virginia dans cette branche conditionnelle. Cela signifie qu'il est classé dans. Cependant, puisque la valeur de * class * est versicle cette fois, il est préférable ** que tous soient classés comme versicle. En d'autres termes, tout ce qui est classé comme ** impuretés ** peut être qualifié de ** impuretés **, de sorte que l'arbre déterminant utilise un indice appelé ** impur ** pour le mesurer quantitativement.

Calculons l'impureté Gini de cet exemple spécifique.


1 - (\dfrac{49}{50})^2 - (\dfrac{5}{50})^2 \approx 0.168

J'ai pu calculer l'impureté de Gini. Vous pouvez voir qu'il correspond à la valeur de * gini * dans le nœud vert.

Entropie

Il est également possible d'utiliser entpy comme indicateur de pureté. L'entropie est un concept qui exprime le ** désordre ** basé sur l'idée de la théorie de l'information. L'image est que si l'entropie est grande, ** désordonné = haute pureté **. L'explication du concept d'entropie est donnée dans Article précédent, veuillez donc vous y référer également.

L'entropie est exprimée par la formule suivante.


H(p) = -\sum_{i=1}^{n} p_{i}log_{2}(p_{i})

Calculons l'enthousiasme du nœud vert comme dans le cas de Gini impur.


-(\dfrac{49}{50})log_{2}(\dfrac{49}{50}) - (\dfrac{5}{50})log_{2}(\dfrac{5}{50}) \approx 0.445

Même sur sklearn, en donnant critère = 'entropie' comme argument lors de l'entraînement d'un modèle, il est possible de procéder à l'entraînement avec l'impureté comme entropie. Dans l'arbre de décision ci-dessous, vous pouvez voir que * entropy * est inclus au lieu de * gini *.

iris_tree.png

En gros, il semble qu'il n'y ait pas de grande différence dans les résultats d'apprentissage entre l'utilisation de ** Gini Impure ** et ** Entropy **, mais l'utilisation de Gini Impure est légèrement meilleure. Il semble que la vitesse de calcul soit rapide.

Algorithme de formation CART

Il y a plusieurs algorithmes dans l'arbre de décision, mais cette fois je vais vous présenter le CART (Classification and Regression Tree) le plus basique. L'algorithme sklearn utilise CART. CART est un algorithme qui crée uniquement des branches conditionnelles à deux choix (Oui ou Non) sur chaque nœud, et crée des branches afin que la fonction de coût illustrée ci-dessous soit minimisée.

Considérez qu'une caractéristique est $ k $ et les données sont divisées en deux au seuil $ t_ {k} $ pour ce $ k $. A ce moment, l'optimum $ k $ et $ t_ {t} $ peut être obtenu en minimisant la fonction de perte suivante.


L(k, t_{t}) = \dfrac{n_{right}}{n}Gini_{right} + \dfrac{n_{left}}{n}Gini_{left}

La signification de la formule ci-dessus est la moyenne pondérée du nombre de données impures du nœud après la division gauche et droite, et vous pouvez trouver le seuil optimal en le minimisant.

Déterminer les paramètres de l'arbre

L'arbre de décision continuera à se ramifier profondément jusqu'à la ligne ** où la pureté ne diminue pas même si elle est davantage divisée. Cependant, étant donné que l'arbre de décision a la propriété de ** facilement surajustement aux données d'entraînement données **, lui permettre de créer des branches à n'importe quelle profondeur peut facilement provoquer un surentraînement.

En guise de contre-mesure, donnez des paramètres qui limitent la forme de l'arbre de décision. Des exemples typiques sont les paramètres qui limitent la profondeur de l'arbre ("max_depth" pour sklearn) et la limite inférieure du nombre d'échantillons requis pour diviser un nœud ("min_sample_leaf" pour sklearn).

Classification des documents à l'aide de l'arbre de décision

Création d'un modèle d'arbre de décision à l'aide de sklearn

Dans ce qui suit, nous allons en fait créer un modèle de l'arbre de décision à l'aide de la bibliothèque.

Bibliothèque utilisée

scikit-learn 0.21.3

base de données

Vous pouvez facilement créer un modèle d'arbre de décision à l'aide de sklearn. Cette fois, nous utiliserons le "corpus d'actualités de livingoor" pour l'ensemble de données. Pour plus de détails sur l'ensemble de données et la méthode d'analyse morphologique, veuillez consulter Publié dans l'article précédemment publié. Je vais.

Dans le cas du japonais, un prétraitement qui décompose les phrases en éléments morphologiques est nécessaire à l'avance, donc après avoir décomposé toutes les phrases en éléments morphologiques, elles sont déposées dans la trame de données suivante.

スクリーンショット 2020-01-13 21.07.38.png

La colonne la plus à droite est l'analyse morphologique de toutes les phrases et séparées par des espaces de demi-largeur. Utilisez-le pour créer un modèle de l'arbre de décision.

Apprentissage de modèle

Créez un modèle de l'arbre de décision à l'aide de sklearn. Voici les principaux paramètres de création d'un modèle.

Le nom du paramètre Signification des paramètres
criterion {“gini”, “entropy”}Utiliser ou non la pureté de Gini ou l'entropie comme indicateur de pureté
max_depth Valeur maximale de la profondeur autorisée de l'arbre de décision(S'il n'est pas défini, il peut être possible de créer un arbre de décision très compliqué, qui est lié aux performances de généralisation.)
min_samples_split En divisant le nœudNombre minimum d'échantillons requis(Si la valeur minimale est petite, un modèle qui se divise finement peut être créé, ce qui est lié aux performances de généralisation.)
min_samples_leaf Nombre minimum d'échantillons à laisser dans la feuille au moins(Comme ci-dessus, si la valeur minimale est petite, un modèle qui divise finement peut être créé, ce qui est lié aux performances de généralisation.)

Cette fois, après avoir converti la phrase au format Sac de mots (en comptant le nombre de mots que chaque mot contient dans chaque phrase et en la vectorisant), le vecteur est appliqué à l'arbre de décision. J'essaierai de classer les articles liés à l'informatique appelés «piratage de la vie» et les articles liés au sport appelés «montre-sport».


import pandas as pd
import pickle

#On suppose que la trame de données après décomposition morphologique a déjà été décapée.
with open('df_wakati.pickle', 'rb') as f:
    df = pickle.load(f)

#Vérifiez si vous pouvez classer deux types d'articles cette fois
ddf = df[(df[1]=='sports-watch') | (df[1]=='it-life-hack')].reset_index(drop = True)

#Phrases de sac en utilisant la bibliothèque de sklearn-of-Convertir au format de mots
from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(token_pattern="(?u)\\b\\w+\\b")
X = vectorizer.fit_transform(ddf[3])

#Convertir le type d'article en valeur numérique
def convert(x):
    if x == 'it-life-hack':
        return 0
    elif x == 'sports-watch':
        return 1

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split

iris = load_iris()

X = X
y = ddf[1].apply(lambda x : convert(x))

#Séparez les données d'entraînement et les données d'évaluation
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7, random_state=42)

#Apprendre le modèle
tree_clf = DecisionTreeClassifier(criterion = 'gini', max_depth=4, min_samples_leaf = 10,random_state=42)
tree_clf.fit(X_train, y_train)

#Sortie du résultat pour les données d'évaluation
print(tree_clf.score(X_test, y_test))

La valeur sortie comme précision est ici. La précision est meilleure que vous ne pouvez l'imaginer. Il semble y avoir une nette différence entre les mots utilisés dans les articles liés à l'informatique et les articles liés au sport.

0.9529190207156308

Visualisons maintenant le modèle créé cette fois.

from graphviz import Source
from sklearn.tree import export_graphviz
import os

export_graphviz(
        tree_clf,
        out_file=os.path.join("text_classification.dot"),
        feature_names=vectorizer.get_feature_names(),
        class_names=['it-life-hack', 'sports-watch'],
        rounded=True,
        filled=True
    )

Ce qui suit est exécuté comme une commande

$ dot -Tpng text_classification.dot -o text_classification.png

iris_tree.png

Vous pouvez voir que des fonctionnalités convaincantes telles que "produit" et "joueur" sont adoptées comme conditions de division des nœuds. C'est un gros avantage que le contenu ne soit pas une boîte noire.

Next Je voudrais étudier pas à pas Random Forest, Adaboost, Xgboost, lightGBM, etc., qui sont les systèmes de développement de l'arbre de décision.

Recommended Posts

Comprendre l'arbre de décision et classer les documents
Arbre de décision et forêt aléatoire
Essayer d'implémenter et de comprendre les arborescences de segments étape par étape (python)
2.Faites un arbre de décision à partir de 0 avec Python et comprenez-le (2. Bases du programme Python)
J'ai essayé de comprendre l'arbre de décision (CART) pour classer soigneusement
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (4. Structure des données)
Créez un arbre de décision à partir de 0 avec Python et comprenez-le (5. Entropie des informations)
Arbre de décision (classification)
Comprendre l'espace de noms TensorFlow et les variables partagées principales
La décision de scikit-learn Comment visualiser un modèle en bois
Comprenez attentivement la distribution exponentielle et dessinez en Python
Visualisez les données et saisissez la corrélation en même temps
Tracer et comprendre la distribution normale multivariée en Python
Comprendre attentivement la distribution de Poisson et dessiner en Python
Créez un arbre de décision à partir de zéro avec Python et comprenez-le (3. Bibliothèque d'analyse de données édition Pandas)
Comprendre le modèle de stratégie en comparant le code JavaScript et Java
Comprendre la différence entre l'affectation cumulative aux variables et l'affectation cumulative aux objets
Comprendre le modèle Decorator en comparant le code JavaScript et Java
Comprendre le modèle d'état en comparant le code JavaScript et Java
"Copie profonde" et "Copie superficielle" à comprendre avec le plus petit exemple
Comprendre le modèle composite en comparant le code JavaScript et Java