[PYTHON] Les débutants en apprentissage automatique essaient de créer un arbre de décision

La dernière fois, j'ai posté Les débutants de l'apprentissage automatique essayent de contacter Naive Bayes, mais cette fois j'aimerais écrire sur l'arbre de décision. (Cette fois aussi, je l'ai implémenté moi-même en Python)

Il y a beaucoup de détails dans d'autres endroits, alors je voudrais ici le décomposer et l'expliquer du point de vue de l'explication et de la programmation.

Qu'est-ce qu'un arbre de décision?

Il s'agit d'une méthode de classification des données d'entrée en générant un classificateur à structure arborescente à partir d'un ensemble de données de variables objectives et de variables explicatives.

Je n'ai pas compris, alors je vais commencer par expliquer les termes.

En général, je pense que ce qui précède est souvent un vecteur. (Cela semble être un apprentissage automatique général)

Mâchez un peu plus l'arbre de décision

En bref, faites beaucoup de «if --elest». C'est.

J'écrirai le flux un peu plus en détail.

c'est tout.

Comment diviser / fonction d'évaluation

Je pense que c'est le cœur de cette époque.

Comment diviser

Je vais vous expliquer comment diviser les données. Les données suivantes sont créées à partir des données d'iris de sklearn.

from sklearn import datasets
iris = datasets.load_iris() #lecture de données d'iris
iris.data #Variable explicative
iris.target #Variable objectif

Considérez l'ensemble de données suivant. La cinquième dimension représente la variable objective (0, 1, 2: type de fleur), et les autres représentent les variables explicatives (longueur des pétales, etc.).

[
[5.1, 3.5, 1.4, 0.2, 0], 
[4.9, 3.0, 1.4, 0.2, 1], 
[4.7, 3.2, 1.3, 0.2, 0]
...
]

Maintenant, que faire lors de la division de ces données est la suivante.

Fonction d'évaluation

Il semble qu'il existe plusieurs méthodes utilisées pour évaluer l'arbre de décision, mais cette fois nous utiliserons "Gini Impure".

Impur ??

Le mot «impur» est apparu pour la première fois, mais c'est facile. C'est bien de se répartir entre les variables explicatives, mais est-ce la bonne façon de se séparer? Je pense que la question demeure. Gini impur est celui qui le quantifie.

D'ailleurs, le mot «coefficient de Gini» a été utilisé sur d'autres sites, mais soyez prudent lors de la recherche car la différenciation ressort d'une manière ou d'une autre (un graphique de la courbe de Lorenz de la population et des revenus en sort. * Je ne sais pas grand chose, alors dites-moi qui le connaît ..)

En ce qui concerne l'impureté de Gini, il est également publié pour référence, mais le site suivant était facile à comprendre. Il est divisé en partie entière / seconde partie.

Coefficient statistique Honey Gini ...? (Partie 1)

Cette impureté gini est calculée pour les ensembles L et R obtenus en divisant l'ensemble A, et la valeur moyenne est prise pour obtenir la pureté gini: G (x).

G (A)> Moyenne de G (L) et G (R)

Si tel est le cas, cela signifie qu'il a été divisé avec succès.

Code source

C'est encore difficile, mais je posterai le code source pour le moment. Veuillez commenter si vous en avez! !!

# -*- coding: utf-8 -*-

from collections import defaultdict

class Sample:

    def __init__(self, label=0, features=[]):
        self.label    = label
        self.features = features

# ----------------------------------------------------------------------------

class Node:

    def __init__(self, level=0):
        self.level       = level #Profondeur de la hiérarchie
        self.l_node      = None  #Nœud enfant(la gauche)
        self.r_node      = None  #Nœud enfant(droite)
        self.t_value     = None  #Seuil
        self.feature_idx = None  #Quelle valeur diviser
        self.label       = None  #Étiquettes à classer
        self.samples     = []    #Échantillon auquel


    def __str__(self):
        if self.is_leaf():
            return "[%3s] Samples:%3s" % (self.level, len(self.samples))
        else:
            return "[%3s] Feature Idx:%3s, Threashold: %5s" % (self.level, self.feature_idx, self.t_value)


    def is_leaf(self):
        return (self.l_node is None) and (self.r_node is None)


    def child_nodes(self):
        return filter(None, [self.l_node, self.r_node])


    def classify(self, feature):
        node  = self
        label = None

        f = feature[node.feature_idx]
        while node:
            if node.is_leaf():
                label = node.label
                break
            elif f < node.t_value:
                node = node.l_node
            else:
                node = node.r_node

        return label


    def build_child_nodes(self, n_class, samples, max_depth, min_samples):
        self.samples = samples
        n_features   = len(samples[0].features) #Nombre de variables explicatives

        #Lorsque vous atteignez la profondeur maximale, vous avez terminé
        if self.level >= max_depth:
            self.build_leaf()
            return

        #Le meilleur résultat du classement
        best_feature_idx = None #Les variables explicatives les mieux classées
        best_t_value     = None #Meilleur seuil classé
        best_gini        = 1    #L'égalité à l'approche de 0
        best_l_samples   = []
        best_r_samples   = []

        #Évaluer en classant autant que le nombre de variables explicatives
        #Classer par chaque variable explicative(idx =Index des variables explicatives)
        for idx in range(0, n_features-1):

            #Rendre les variables explicatives à classer uniques et les trier par ordre croissant
            features = map(lambda x: x.features[idx] , samples)
            features = list(set(features))
            features.sort()

            for i in range(0, len(features)-2):

                #Classer par la valeur intermédiaire de chaque variable explicative.
                t_value = (features[i] + features[i+1]) / 2

                l_samples = []; l_sample_labels = defaultdict(lambda: 0)
                r_samples = []; r_sample_labels = defaultdict(lambda: 0)
                for s in samples:

                    if s.features[idx] < t_value:
                        l_samples.append(s)
                        l_sample_labels[s.label] += 1
                    else:
                        r_samples.append(s)
                        r_sample_labels[s.label] += 1

                #Il ne sert à rien de diviser si cela est,Calcul des variables explicatives suivantes
                if len(l_samples) == 0 or len(r_samples) == 0:
                    continue

                #Évaluation pour les divisés(coefficient de Gini,Entropie croisée)
                l_gini = 0; r_gini = 0
                for idx in range(0, n_class):
                    l_gini += (float(l_sample_labels[idx]) / len(l_samples)) ** 2
                    r_gini += (float(r_sample_labels[idx]) / len(r_samples)) ** 2

                #Coefficient de Gini global(l,Trouvez la valeur moyenne du coefficient gini de r)
                gini = (((1-l_gini) * len(l_samples)) + ((1-r_gini) * len(r_samples))) / len(samples)

                #Mettre à jour si meilleur que le meilleur
                if gini < best_gini:
                    best_gini        = gini
                    best_t_value     = t_value
                    best_feature_idx = idx
                    best_l_samples   = l_samples
                    best_r_samples   = r_samples

        #Si vous êtes biaisé d'un côté ou de l'autre, ne créez pas de nouvel arbre
        if len(best_l_samples) == 0 or len(best_r_samples) == 0:
            self.build_leaf()
            return

        # min_Pas besoin de séparer si les échantillons ne sont pas atteints.Mesures de surapprentissage
        if max(len(best_l_samples), len(best_r_samples)) < min_samples:
            self.build_leaf()
            return

        #Paramètres de nœud actuels
        self.samples     = []
        self.t_value     = best_t_value
        self.feature_idx = best_feature_idx

        #Créez un nouveau nœud parmi les meilleurs,Passer au nœud suivant
        next_level = self.level + 1

        self.r_node = Node(next_level)
        self.r_node.build_child_nodes(n_class, best_r_samples, max_depth, min_samples)

        self.l_node = Node(next_level)
        self.l_node.build_child_nodes(n_class, best_l_samples, max_depth, min_samples)


    def build_leaf(self):
        self.label = self.samples[0].label

# ----------------------------------------------------------------------------

class DecisionTree:

    def __init__(self, max_depth=10, min_samples=3):
        self.root_node   = Node(level=1) # root node
        self.max_depth   = max_depth     #Profondeur maximale de l'arbre
        self.min_samples = min_samples   #Nombre minimum d'éléments appartenant à Node


    def fit(self, data, target):
        #Nombre de classes de classification uniques
        labels = list(set(target))

        #Génération de données pour la formation
        samples = []
        for idx, sample in enumerate(data):
            samples.append(Sample(features=data[idx], label=target[idx]))

        #Apprentissage
        self.root_node.build_child_nodes(n_class=len(labels), samples=samples, max_depth=self.max_depth, min_samples=self.min_samples)


    def features(self):
        #Fonctionnalités du nœud de sortie pour chaque niveau
        print self.root_node

        current_nodes = self.root_node.child_nodes()
        child_nodes   = []
        while current_nodes:
            node = current_nodes.pop(0)
            print node
            child_nodes.extend(node.child_nodes())

            if len(current_nodes) == 0 and len(child_nodes) > 0:
                current_nodes = child_nodes
                child_nodes   = []


    def predict(self, data):
        return self.root_node.classify(data)

référence

La page suivante a été très utile.

Recommended Posts

Les débutants en apprentissage automatique essaient de créer un arbre de décision
Machine Learning: Supervisé - Arbre de décision
[Apprentissage automatique] Étudions l'arbre de décision
Apprentissage automatique ③ Résumé de l'arbre de décision
Les débutants en apprentissage automatique tentent de contacter Naive Bayes (2) - Mise en œuvre
Les débutants en apprentissage automatique tentent de contacter Naive Bayes (1) - Théorie
Faisons un noyau jupyter
Essayez de faire une stratégie de blackjack en renforçant l'apprentissage ((1) Implémentation du blackjack)
Comment créer un système de dialogue dédié aux débutants
Essayez de prédire la demande de puissance par l'apprentissage automatique
Les débutants en IA essaient de faire des étudiants professionnels Bot
Essayez de créer un code de "décryptage" en Python
Essayez de créer un groupe de dièdre avec Python
[Pour les débutants] Introduction à la vectorisation dans l'apprentissage automatique
Introduction à l'apprentissage automatique
Essayez de dessiner un "front de type carte météorologique" par apprentissage automatique basé sur des données météorologiques (5)
Essayez de dessiner un "front de type carte météo" par apprentissage automatique basé sur les données météorologiques (3)
Essayez de dessiner un "front de type carte météo" par apprentissage automatique basé sur des données météorologiques (1)
Essayez de dessiner un "front de type carte météo" par apprentissage automatique basé sur des données météorologiques (4)
Essayez de dessiner un "front de type carte météo" par apprentissage automatique basé sur des données météorologiques (2)
Essayez de créer un module Python en langage C
Faisons un outil de veille de commande avec python
Essayez de prédire le taux de change (FX) avec un apprentissage automatique non approfondi
[Apprentissage automatique] Essayez de détecter des objets à l'aide de la recherche sélective
Introduction à l'apprentissage automatique à partir de Simple Perceptron
Tout pour que les débutants puissent faire du machine learning
J'ai essayé de faire une simulation de séparation de source sonore en temps réel avec l'apprentissage automatique Python
Essayez de faire une stratégie de blackjack en renforçant l'apprentissage (② Enregistrer l'environnement dans le gymnase)
Une introduction à l'apprentissage automatique
Un débutant en apprentissage automatique a essayé la RBM
Créer un environnement d'apprentissage automatique
Super introduction à l'apprentissage automatique
Essayez le machine learning à la légère avec Kaggle
Essayez de sélectionner une langue
Essayez de créer un réseau de neurones / d'apprentissage en profondeur avec scratch
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de régression
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de classification
Un résumé de l'apprentissage automatique Python pour débutant est très concis.
[Introduction à Tensorflow] Comprendre correctement Tensorflow et essayer de créer un modèle
Essayez de faire une stratégie de blackjack en renforçant l'apprentissage (③ Renforcer l'apprentissage dans votre propre environnement OpenAI Gym))
Comment faire une traduction japonais-anglais
Introduction à la rédaction de notes d'apprentissage automatique
Essayez de dessiner une courbe de Bézier
[Tutoriel] Créez un extracteur d'expressions unique en 30 minutes à l'aide de l'apprentissage automatique
Créer un arbre déterminé avec scikit-learn
[Apprentissage automatique] Essayez d'exécuter Spark MLlib avec Python et faites des recommandations
Résumé de l'apprentissage automatique par les débutants de Python
Comment créer un bot slack
Comment créer une fonction récursive
Essayez de créer un type de service Web avec un langage de balisage 3D
SVM essayant l'apprentissage automatique avec scikit-learn
Analyse inverse du modèle d'apprentissage automatique
[Introduction] Je veux créer un robot Mastodon avec Python! 【Débutants】
[Blender] Comment créer un plug-in Blender
Présentation de la bibliothèque d'apprentissage automatique SHOGUN
[Apprentissage automatique] Essayez d'étudier une forêt aléatoire
Je souhaite créer un service d'apprentissage automatique sans programmation! API Web
Comment créer un robot - Basic
Comment collecter des données d'apprentissage automatique
Comment créer une API de machine learning sans serveur avec AWS Lambda