[PYTHON] Ich habe versucht, den entscheidenden Baum (CART) zu verstehen, um ihn sorgfältig zu klassifizieren

Einführung

Bisher haben wir die logistische Regression zusammengefasst, unterstützen Vektormaschinen, neuronale Netze usw. Dieses Mal werde ich die grundlegenden Entscheidungsbäume wie XGBoost, LightGBM und Random Forest zusammenfassen.

Was ist ein Entscheidungsbaum?

Ein Entscheidungsbaum ist ein Algorithmus, der "Daten Schritt für Schritt trennt und baumartige Analyseergebnisse ausgibt".

021.png

Die Vorteile einer Analyse mit diesem Entscheidungsbaum sind:

Es gibt Funktionen wie. Insbesondere finde ich den ersten Vorteil großartig. Andere Klassifizierer (Support-Vektor-Maschinen, neuronale Netze usw.) sind sehr kompliziert und in den darin durchgeführten Berechnungen Black-Box-fähig, sodass es für jeden, der mit dem Inhalt des Modells vertraut ist, schwierig ist, den Inhalt zu verstehen. Da ist ein Gesicht. Andererseits ist der Entscheidungsbaum ein leicht verständliches Merkmal, da die Gründe für die Teilung klar sind, wie in der obigen Abbildung gezeigt. Ich denke das ist ** leicht zu verstehen ** ein großer Vorteil. Dies liegt daran, dass ich nicht denke, dass es eine gute Einstellung für einen Techniker für eine Person ist, die ein Modell verwendet, um Ergebnisse mit etwas zu erzielen, das sie nicht verstehen **.

Dieser Entscheidungsbaum ist ein Algorithmus, der sowohl auf die Klassifizierung als auch auf die Regression angewendet werden kann. Dieses Mal möchte ich jedoch die Klassifizierung zusammenfassen. Darüber hinaus verfügt der Entscheidungsbaum über einen Algorithmus namens CART und C4.5. Diesmal geht es um CART.

Wie man die Kriterien für die Teilung entscheidet

Teilen Sie so, dass die Elemente nach der Teilung (zu teilende Daten) für jedes Element gelten, das Sie teilen möchten (= die Reinheit nach der Teilung ist das Minimum). Unreinheit ist ein Indikator dafür, wie verschiedene Klassen von Elementen miteinander vermischt werden.

Ich möchte es kurz mit einem Beispiel betrachten. Ich möchte die make_blobs () Methode von scikit learn laden und erstellen, die mir eine Sprühprobe gibt.

RF.ipynb


#Imports
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn

from sklearn.datasets import make_blobs

X, y = make_blobs(n_samples=500, centers=4,
                  random_state=8, cluster_std=2.2)

#Scatter plot the points
plt.figure(figsize=(10,10))
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='jet')

Das ursprüngliche Streudiagramm ist hier.

022.png

Lassen Sie uns nun darüber nachdenken, wie Sie dieses Streudiagramm teilen können.

image.png

Aufgrund der Trennlinie links das Element $ [2], gegenüber der Gruppe mit vielen Elementen $ [0], [1] $ (umgekehrt ohne $ [2], [3] $) Sie können sehen, dass es in Gruppen unterteilt werden kann, die viel [3] $ enthalten (umgekehrt sind $ [0] und [1] $ nicht enthalten). Diese Art der Teilung ist eine Teilungsmethode mit geringerer Reinheit. Andererseits können Sie im Fall der Trennlinie rechts sehen, dass die Elemente von $ [0] bis [3] $ nach dem Teilen in der Gruppe gemischt werden. Dies wird als mit vielen Verunreinigungen bezeichnet. Suchen Sie die Trennlinie wie links gezeigt und klassifizieren Sie sie mehrmals (= Tiefe des Entscheidungsbaums genannt), um den Zweck zu klassifizieren.

Wie man Reinheit findet

Lassen Sie uns nun zusammenfassen, wie diese Unreinheit ausgedrückt werden kann. Dieses Mal konzentrieren wir uns auf Ginis Diversity Index $. Die wörtliche Übersetzung ist der Gini Diversity Index. Ich denke, Sie können die Bedeutung auf Japanisch verstehen, aber es scheint, dass es oft als unrein bezeichnet wird.

Betrachten Sie eine Hierarchie (= Knoten) $ t $ mit einem Entscheidungsbaum. Ein Knoten ist eine Gruppe, nachdem er aufgeteilt wurde. Betrachten Sie dann den Fall, in dem sich $ n $ Samples im Knoten und $ c $ Klassen im Knoten befinden. Unter der Annahme, dass die Anzahl der zur Klasse $ i $ gehörenden Abtastwerte im Knoten $ t $ $ n_i $ ist, kann zu diesem Zeitpunkt das Verhältnis der Abtastwerte, die zur Klasse $ i $ p (i | t) $ gehören, wie folgt ausgedrückt werden. Ich kann es schaffen

p(i|t) = \frac{n_i}{n} \tag{1}

Zu diesem Zeitpunkt kann Gini Impure $ I_G (t) $ wie folgt ausgedrückt werden. $ I_G(t) = 1 - \sum_{i=1}^c {p(i|t)}^2 \tag{2} $

Die Summe von $ p (i | t) ^ 2 $ erhöht sich, wenn eine gute Division vorgenommen wird. Daher wird $ I_G (t) $ kleiner. Mit diesem Bewertungsindex werden wir einen guten Klassifikator erstellen.

Angeordnet, damit das Diagramm besser sichtbar ist

Färben Sie jede Klasse aus, um das Verständnis zu erleichtern.

RF.ipynb


def visualize_tree(classifier, X, y, boundaries=True,xlim=None, ylim=None):
    '''
Visualisieren Sie den Entscheidungsbaum.
    INPUTS:Klassifizierungsmodell, X, y, optional x/y limits.
    OUTPUTS:Visualisierung von Entscheidungsbäumen mit Meshgrid
    '''
    #Erstellen eines Modells mit fit
    classifier.fit(X, y)
    
    #Automatische Einstellung der Achse
    if xlim is None:
        xlim = (X[:, 0].min() - 0.1, X[:, 0].max() + 0.1)
    if ylim is None:
        ylim = (X[:, 1].min() - 0.1, X[:, 1].max() + 0.1)

    x_min, x_max = xlim
    y_min, y_max = ylim
    
    
    #Erstellen Sie ein Netzgitter.
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100),
                         np.linspace(y_min, y_max, 100))
    
    #Speichern Sie Klassifikatorvorhersagen als Z.
    Z = classifier.predict(np.c_[xx.ravel(), yy.ravel()])

    #Verwenden Sie Meshgrid, um es zu formen.
    Z = Z.reshape(xx.shape)
    
    #Färben Sie jede Kategorie.
    plt.figure(figsize=(10,10))
    plt.pcolormesh(xx, yy, Z, alpha=0.2, cmap='jet')
    
    #Es werden auch Trainingsdaten gezeichnet.
    plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='jet')
    
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)        
    
    def plot_boundaries(i, xlim, ylim):
        '''
Zeichne einen Rand.
        '''
        if i < 0:
            return

        tree = classifier.tree_
        
        #Rufen Sie rekursiv auf, um die Grenzen zu ziehen.
        if tree.feature[i] == 0:
            plt.plot([tree.threshold[i], tree.threshold[i]], ylim, '-k')
            plot_boundaries(tree.children_left[i],
                            [xlim[0], tree.threshold[i]], ylim)
            plot_boundaries(tree.children_right[i],
                            [tree.threshold[i], xlim[1]], ylim)
        
        elif tree.feature[i] == 1:
            plt.plot(xlim, [tree.threshold[i], tree.threshold[i]], '-k')
            plot_boundaries(tree.children_left[i], xlim,
                            [ylim[0], tree.threshold[i]])
            plot_boundaries(tree.children_right[i], xlim,
                            [tree.threshold[i], ylim[1]])
    
    if boundaries:
        plot_boundaries(0, plt.xlim(), plt.ylim())

Versuchen Sie, nach Entscheidungsbaum zu klassifizieren

RF.ipynb


from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(criterion='entropy',max_depth=2,random_state=0)

visualize_tree(clf,X,y)

023.png

Ich konnte es in ein gutes Gefühl aufteilen. Bestimmen Sie oben die Tiefe des ermittelten Baums mit "max_depth". Das Erhöhen (= Vertiefen) des Werts dieser "max_depth" führt zu Überlernen. Versuchen Sie es mit max_depth = 6.

024.png

Sie können sehen, dass es überteilt ist (insbesondere die rote Klasse). Der Punkt ist, dass Sie diese Tiefe selbst anpassen müssen.

Visualisierung der Basis des Entscheidungsbaums

Übrigens ist das Bild des Entscheidungsbaums bei Überprüfung in Tiefe 2 unten dargestellt.

image.png

Die numerischen Werte und die Gini-Unreinheit, die als Kriterien für die Klassifizierung dienen, werden aufgelistet. value ist die Anzahl der Elemente in den Klassen [0] bis [3].

So geben Sie ein Entscheidungsbaumbild aus

Übrigens ist es ein schnelles Image, aber es ist notwendig, die Bibliothek zu importieren und die Software zu installieren.

  1. Installieren Sie pydotplus
  2. Installieren Sie graphviz
  3. Durch den Weg

Die oben genannten drei Aktionen waren notwendig, um zu retten.

  1. Installieren Sie pydotplus

Dies ist eine Bibliothek, die den durch den Entscheidungsbaum geteilten Inhalt in einer ".dot" -Datei speichert.

console


pip install pydotplus

Wie bei jeder anderen Bibliothek können Sie sie mit pip installieren.

  1. Installieren Sie graphviz

Ich habe das Installationsprogramm (graphviz-2.38.msi) von dieser URL heruntergeladen.

https://graphviz.gitlab.io/_pages/Download/Download_windows.html

Wenn der Download abgeschlossen ist, doppelklicken Sie auf "graphviz-2.38.msi", um ihn zu installieren. Installieren Sie außerdem graph viz auf pip.

  1. Übergeben Sie den Pfad

Übergeben Sie dann "Pfad", um es als PDF zu erstellen. Geben Sie den Ordner an, in dem sich dot.exe befindet. Ich habe die Methode bereits zusammengefasst, siehe hier.

https://qiita.com/Fumio-eisan/items/340de9fe220a90607013

Schließlich müssen Sie die Syntax in graphviz.py wie folgt umschreiben:

image.png

Zu diesem Zeitpunkt kann der Entscheidungsbaum in .dot und pdf konvertiert werden.

RF.ipynb



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

export_graphviz(
        clf,
        out_file=os.path.join("text_classification.dot"),
        class_names=['1', '2','3','4'],
        rounded=True,
        filled=True
    )
with open("random.dot", 'w') as f:
    f = export_graphviz(clf, out_file=f)

data = export_graphviz(clf, out_file=None)
graph = pydotplus.graph_from_dot_data(data)
graph.write_pdf("random.pdf")

Ich habe auf diese Seite verwiesen.

GraphViz-Fehlerbehandlung (ausführbare Dateien von GraphViz nicht gefunden) https://niwakomablog.com/graphviz-error-handling/

Am Ende

Dieses Mal haben wir den Inhalt und die Implementierung der Klassifizierung von Entscheidungsbäumen zusammengefasst. Die Idee ist leicht zu verstehen und leicht umzusetzen. Am Ende hatte ich jedoch das Gefühl, dass es eine kleine Hürde war, den Entscheidungsbaum in ein PDF umzuwandeln. Als nächstes möchte ich zurückkehren.

Das vollständige Programm finden Sie hier. https://github.com/Fumio-eisan/RF_20200423

Recommended Posts

Ich habe versucht, den entscheidenden Baum (CART) zu verstehen, um ihn sorgfältig zu klassifizieren
Python-Übung 100 Schläge Ich habe versucht, den Entscheidungsbaum von Kapitel 5 mit graphviz zu visualisieren
[Einführung] Ich habe versucht, es selbst zu implementieren, während ich erklärte, um die Dichotomie zu verstehen
Ich habe versucht, den Ball zu bewegen
Ich habe versucht, den Abschnitt zu schätzen.
(Python) Erwarteter Wert ・ Ich habe versucht, die Monte-Carlo-Probenahme sorgfältig zu verstehen
Ich habe versucht, eine Site zu erstellen, mit der die aktualisierten Informationen von Azure einfach angezeigt werden können
Ich habe versucht, den Befehl umask zusammenzufassen
Ich versuchte das Weckwort zu erkennen
Verstehen Sie den Entscheidungsbaum und klassifizieren Sie Dokumente
Ich habe versucht, das Umfangsverhältnis π probabilistisch abzuschätzen
Ich habe versucht, die COTOHA-API zu berühren
(Maschinelles Lernen) Ich habe versucht, die Bayes'sche lineare Regression bei der Implementierung sorgfältig zu verstehen
(Maschinelles Lernen) Ich habe versucht, den EM-Algorithmus in der gemischten Gaußschen Verteilung sorgfältig mit der Implementierung zu verstehen.
Ich habe Web Scraping versucht, um die Texte zu analysieren.
Ich habe versucht, beim Trocknen der Wäsche zu optimieren
Ich habe versucht, die Daten mit Zwietracht zu speichern
Entscheidungsbaum (Klassifikation)
Ich habe versucht, die Pferde vorherzusagen, die mit LightGBM unter den Top 3 sein werden
Ich habe versucht, die Trapezform des Bildes zu korrigieren
Qiita Job Ich habe versucht, den Job zu analysieren
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (erste Hälfte).
Ich habe die Größenänderung von TensorFlow nicht verstanden und sie daher visuell zusammengefasst.
LeetCode Ich habe versucht, die einfachen zusammenzufassen
Ich habe versucht, das Problem des Handlungsreisenden umzusetzen
Ich habe versucht, die Support-Vektor-Maschine sorgfältig zu verstehen (Teil 1: Ich habe den Polynom / RBF-Kernel am Beispiel von MakeMoons ausprobiert).
Ich habe versucht, die Texte von Hinatazaka 46 zu vektorisieren!
[LPIC 101] Ich habe versucht, die Befehlsoptionen zusammenzufassen, die leicht zu Fehlern führen können
[Einführung] Ich habe versucht, es selbst zu implementieren, während ich den Dichotomiebaum erklärte
Ich habe versucht zu verstehen, wie Pandas und multiple Co-Linearität unter Verwendung des Affairs-Datensatzes als Thema verwendet werden.
mong - Ich habe versucht, den Code, der zufällig den Containernamen von Docker generiert, nach Python zu portieren. -
Ich habe versucht, die Sündenfunktion mit Chainer zu trainieren
Ich habe versucht, die in Python installierten Pakete grafisch darzustellen
Ich habe versucht, die Grundform von GPLVM zusammenzufassen
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, das Spiel in der J League vorherzusagen (Datenanalyse)
Die Entscheidung von scikit-learn Wie man ein Holzmodell visualisiert
Ich habe versucht, Soma Cube mit Python zu lösen
Ich möchte die Grundlagen von Bokeh vollständig verstehen
Ich habe versucht, die Sündenfunktion mit Chainer zu approximieren
Ich habe versucht, Pytest in die eigentliche Schlacht zu bringen
Ich habe versucht, die Spacha-Informationen von VTuber zu visualisieren
Ich habe versucht, den negativen Teil von Meros zu löschen
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich hatte das Gefühl, dass ich den Python-Code nach C ++ 98 portiert habe.
Ich habe versucht, die Methode zur Mittelung der Dollarkosten zu simulieren
Ich habe versucht, die nicht negative Matrixfaktorisierung (NMF) zu wiederholen.
Ich habe die einfachste Methode zur Klassifizierung von Dokumenten mit mehreren Etiketten ausprobiert
Ich habe versucht, die Sprache mit CNN + Melspectogram zu identifizieren
Ich habe versucht, das Wissensdiagramm mit OpenKE zu ergänzen
Ich habe versucht, die Stimmen der Sprecher zu klassifizieren
Ich habe versucht, das Bild mithilfe von maschinellem Lernen zu komprimieren
Ich habe versucht, die String-Operationen von Python zusammenzufassen
Ich habe versucht, es sorgfältig zu verstehen, während ich den Algorithmus Adaboost beim maschinellen Lernen implementiert habe (+ ich habe mein Verständnis der Array-Berechnung vertieft)
Ich habe versucht zu debuggen.