Kann ich die zugrunde liegenden Entscheidungsregeln (oder 'Entscheidungspfade') aus einem trainierten Baum in einem Entscheidungsbaum als Textliste extrahieren?
Etwas wie:
if A>0.4 then if B<0.2 then if C>0.8 then class='X'
Danke für Ihre Hilfe.
python
machine-learning
scikit-learn
decision-tree
random-forest
Dror Hilman
quelle
quelle
Antworten:
Ich glaube, dass diese Antwort korrekter ist als die anderen Antworten hier:
Dies druckt eine gültige Python-Funktion aus. Hier ist eine Beispielausgabe für einen Baum, der versucht, seine Eingabe zurückzugeben, eine Zahl zwischen 0 und 10.
Hier sind einige Stolpersteine, die ich in anderen Antworten sehe:
tree_.threshold == -2
Entscheidung, ob ein Knoten ein Blatt ist, ist keine gute Idee. Was ist, wenn es sich um einen echten Entscheidungsknoten mit einem Schwellenwert von -2 handelt? Stattdessen sollten Sie sichtree.feature
oder ansehentree.children_*
.features = [feature_names[i] for i in tree_.feature]
stürzt mit meiner Version von sklearn ab, da einige Werte vontree.tree_.feature
-2 sind (speziell für Blattknoten).quelle
print "{}return {}".format(indent, tree_.value[node])
sollte geändert werden,print "{}return {}".format(indent, np.argmax(tree_.value[node][0]))
damit die Funktion den Klassenindex zurückgibt .RandomForestClassifier.estimators_
, aber ich konnte nicht herausfinden, wie die Ergebnisse der Schätzer kombiniert werden können.print "bla"
=>print("bla")
Ich habe meine eigene Funktion erstellt, um die Regeln aus den von sklearn erstellten Entscheidungsbäumen zu extrahieren:
Diese Funktion beginnt zuerst mit den Knoten (in den untergeordneten Arrays mit -1 gekennzeichnet) und findet dann rekursiv die übergeordneten Knoten. Ich nenne dies die "Linie" eines Knotens. Unterwegs greife ich zu den Werten, die ich erstellen muss, wenn / dann / sonst SAS-Logik:
Die folgenden Tupelgruppen enthalten alles, was ich zum Erstellen von SAS if / then / else-Anweisungen benötige. Ich mag es nicht,
do
Blöcke in SAS zu verwenden, weshalb ich eine Logik erstelle, die den gesamten Pfad eines Knotens beschreibt. Die einzelne Ganzzahl nach den Tupeln ist die ID des Endknotens in einem Pfad. Alle vorhergehenden Tupel bilden zusammen diesen Knoten.quelle
(0.5, 2.5]
. Die Bäume werden mit rekursiver Partitionierung erstellt. Nichts hindert eine Variable daran, mehrmals ausgewählt zu werden.Ich habe den von Zelazny7 übermittelten Code geändert , um einen Pseudocode zu drucken:
Wenn Sie
get_code(dt, df.columns)
dasselbe Beispiel aufrufen, erhalten Sie:quelle
(threshold[node] != -2)
zu( left[node] != -1)
(ähnlich der folgenden Methode zum Abrufen von IDs vonScikit Learn führte eine köstliche neue Methode ein, die
export_text
in Version 0.21 (Mai 2019) aufgerufen wurde , um die Regeln aus einem Baum zu extrahieren. Dokumentation hier . Es ist nicht mehr erforderlich, eine benutzerdefinierte Funktion zu erstellen.Sobald Sie Ihr Modell angepasst haben, benötigen Sie nur zwei Codezeilen. Importieren Sie zunächst
export_text
:Zweitens erstellen Sie ein Objekt, das Ihre Regeln enthält. Verwenden Sie das
feature_names
Argument und übergeben Sie eine Liste Ihrer Feature-Namen, damit die Regeln besser lesbar sind . Wenn beispielsweise Ihr Modell aufgerufen wirdmodel
und Ihre Features in einem aufgerufenen Datenrahmen benannt sindX_train
, können Sie ein Objekt mit dem Namen erstellentree_rules
:Dann einfach ausdrucken oder speichern
tree_rules
. Ihre Ausgabe sieht folgendermaßen aus:quelle
In der Version 0.18.0 gibt es eine neue
DecisionTreeClassifier
Methode . Die Entwickler bieten eine umfangreiche (gut dokumentierte) exemplarische Vorgehensweisedecision_path
.Der erste Codeabschnitt in der exemplarischen Vorgehensweise, der die Baumstruktur druckt, scheint in Ordnung zu sein. Ich habe jedoch den Code im zweiten Abschnitt geändert, um ein Beispiel abzufragen. Meine Änderungen bezeichnet mit
# <--
Bearbeiten Die
# <--
im folgenden Code gekennzeichneten Änderungen wurden seitdem im exemplarischen Link aktualisiert, nachdem auf die Fehler in den Pull-Anforderungen Nr. 8653 und Nr. 10951 hingewiesen wurde . Es ist jetzt viel einfacher, mitzumachen.Ändern Sie die
sample_id
, um die Entscheidungspfade für andere Beispiele anzuzeigen. Ich habe die Entwickler nicht nach diesen Änderungen gefragt, sondern schien beim Durcharbeiten des Beispiels nur intuitiver zu sein.quelle
Sie können einen Digraphenbaum sehen. Dann sind
clf.tree_.feature
undclf.tree_.value
Array von Knoten, die das Merkmal aufteilen, bzw. Array von Knotenwerten. Weitere Details finden Sie in dieser Github-Quelle .quelle
Nur weil alle so hilfreich waren, füge ich einfach eine Modifikation zu Zelazny7 und Danieles schönen Lösungen hinzu. Dieser ist für Python 2.7 mit Registerkarten, um die Lesbarkeit zu verbessern:
quelle
Die folgenden Codes sind mein Ansatz unter Anaconda Python 2.7 sowie der Paketname "pydot-ng" zum Erstellen einer PDF-Datei mit Entscheidungsregeln. Ich hoffe es ist hilfreich.
Eine Baumgrafik zeigt hier
quelle
Ich habe das durchgemacht, aber ich brauchte die Regeln, um in diesem Format geschrieben zu werden
Also habe ich die Antwort von @paulkernfeld (danke) angepasst, die Sie an Ihre Bedürfnisse anpassen können
quelle
Hier ist eine Möglichkeit, den gesamten Baum mithilfe der SKompiler- Bibliothek in einen einzelnen (nicht unbedingt zu lesbaren) Python-Ausdruck zu übersetzen :
quelle
Dies baut auf der Antwort von @paulkernfeld auf. Wenn Sie einen Datenrahmen X mit Ihren Funktionen und einen Zieldatenrahmen y mit Ihren Antworten haben und eine Vorstellung davon erhalten möchten, welcher y-Wert in welchem Knoten endete (und auch, um ihn entsprechend zu zeichnen), können Sie Folgendes tun:
nicht die eleganteste Version, aber es macht den Job ...
quelle
Dies ist der Code, den Sie benötigen
Ich habe den beliebtesten Code so geändert, dass er in einem Jupyter Notebook Python 3 korrekt eingerückt ist
quelle
Hier ist eine Funktion zum Drucken von Regeln eines Scikit-Learn-Entscheidungsbaums unter Python 3 und mit Offsets für bedingte Blöcke, um die Struktur besser lesbar zu machen:
quelle
Sie können es auch informativer gestalten, indem Sie unterscheiden, zu welcher Klasse es gehört, oder indem Sie sogar den Ausgabewert angeben.
quelle
Hier ist mein Ansatz, um die Entscheidungsregeln in einer Form zu extrahieren, die direkt in SQL verwendet werden kann, damit die Daten nach Knoten gruppiert werden können. (Basierend auf den Ansätzen früherer Poster.)
Das Ergebnis sind nachfolgende
CASE
Klauseln, die in eine SQL-Anweisung kopiert werden können, z.SELECT COALESCE(*CASE WHEN <conditions> THEN > <NodeA>*, > *CASE WHEN <conditions> THEN <NodeB>*, > ....)NodeName,* > FROM <table or view>
quelle
Jetzt können Sie export_text verwenden.
Ein vollständiges Beispiel aus [sklearn] [1]
quelle
Der Code von Zelazny7 wurde geändert, um SQL aus dem Entscheidungsbaum abzurufen.
quelle
Anscheinend hat sich schon vor langer Zeit jemand entschlossen, die folgenden Funktionen zu den Baum-Exportfunktionen des offiziellen Scikits hinzuzufügen (die grundsätzlich nur export_graphviz unterstützen).
Hier ist sein volles Engagement:
https://github.com/scikit-learn/scikit-learn/blob/79bdc8f711d0af225ed6be9fdb708cea9f98a910/sklearn/tree/export.py
Ich bin mir nicht ganz sicher, was mit diesem Kommentar passiert ist. Sie können aber auch versuchen, diese Funktion zu verwenden.
Ich denke, dies rechtfertigt eine ernsthafte Dokumentationsanfrage an die guten Leute von scikit-learn, um die
sklearn.tree.Tree
API, die die zugrunde liegende Baumstruktur darstellt, dieDecisionTreeClassifier
als Attribut verfügbar gemacht wird, ordnungsgemäß zu dokumentierentree_
.quelle
Verwenden Sie einfach die Funktion von sklearn.tree wie folgt
Und dann suchen Sie in Ihrem Projektordner nach der Datei tree.dot , kopieren Sie den gesamten Inhalt und fügen Sie ihn hier ein http://www.webgraphviz.com/ und generieren Sie Ihr Diagramm :)
quelle
Vielen Dank für die wunderbare Lösung von @paulkerfeld. Hinzu kommt seine Lösung für all diejenigen , die eine serialisierte Version von Bäumen haben möchten, benutzen Sie einfach
tree.threshold
,tree.children_left
,tree.children_right
,tree.feature
undtree.value
. Da die Blätter keine Spalten und daher keine Merkmalsnamen und Kinder haben, ist ihr Platzhalter intree.feature
undtree.children_***
sind_tree.TREE_UNDEFINED
und_tree.TREE_LEAF
. Jedem Split wird ein eindeutiger Index zugewiesendepth first search
.Beachten Sie, dass das
tree.value
von Form ist[n, 1, 1]
quelle
Hier ist eine Funktion, die Python-Code aus einem Entscheidungsbaum generiert, indem sie die Ausgabe von konvertiert
export_text
:Beispielnutzung:
Beispielausgabe:
Das obige Beispiel wird mit generiert
names = ['f'+str(j+1) for j in range(NUM_FEATURES)]
.Ein praktisches Feature ist, dass es kleinere Dateigrößen mit reduziertem Abstand erzeugen kann. Einfach einstellen
spacing=2
.quelle