Czy mogę wyodrębnić podstawowe reguły decyzyjne (lub „ścieżki decyzji”) z wytrenowanego drzewa w drzewie decyzyjnym jako listę tekstową?
Coś jak:
if A>0.4 then if B<0.2 then if C>0.8 then class='X'
Dzięki za pomoc.
python
machine-learning
scikit-learn
decision-tree
random-forest
Dror Hilman
źródło
źródło
Odpowiedzi:
Uważam, że ta odpowiedź jest bardziej poprawna niż inne odpowiedzi tutaj:
Spowoduje to wyświetlenie prawidłowej funkcji Pythona. Oto przykładowe dane wyjściowe dla drzewa, które próbuje zwrócić swoje dane wejściowe, liczbę od 0 do 10.
Oto kilka przeszkód, które widzę w innych odpowiedziach:
tree_.threshold == -2
do decydowania, czy węzeł jest liściem, nie jest dobrym pomysłem. A co, jeśli jest to prawdziwy węzeł decyzyjny z progiem -2? Zamiast tego powinieneś spojrzeć natree.feature
lubtree.children_*
.features = [feature_names[i] for i in tree_.feature]
ulega awarii w mojej wersji sklearn, ponieważ niektóre wartościtree.tree_.feature
to -2 (szczególnie dla węzłów liści).źródło
print "{}return {}".format(indent, tree_.value[node])
należy zmienić na,print "{}return {}".format(indent, np.argmax(tree_.value[node][0]))
aby funkcja zwracała indeks klasy.RandomForestClassifier.estimators_
, ale nie byłem w stanie wymyślić, jak połączyć wyniki estymatorów.print "bla"
=>print("bla")
Stworzyłem własną funkcję, aby wyodrębnić reguły z drzew decyzyjnych utworzonych przez sklearn:
Ta funkcja najpierw zaczyna się od węzłów (identyfikowanych przez -1 w tablicach potomnych), a następnie rekurencyjnie znajduje rodziców. Nazywam to „rodowodem” węzła. Po drodze pobieram wartości, które muszę utworzyć logika if / then / else SAS:
Poniższe zestawy krotek zawierają wszystko, czego potrzebuję, aby utworzyć instrukcje SAS if / then / else. Nie lubię używać
do
bloków w SAS, dlatego tworzę logikę opisującą całą ścieżkę węzła. Pojedyncza liczba całkowita po krotkach to identyfikator węzła końcowego w ścieżce. Wszystkie powyższe krotki łączą się, tworząc ten węzeł.źródło
(0.5, 2.5]
. Drzewa są tworzone z rekurencyjnym partycjonowaniem. Nic nie stoi na przeszkodzie, aby zmienna była wybierana wielokrotnie.Zmodyfikowałem kod przesłany przez Zelazny7, aby wydrukować jakiś pseudokod:
jeśli skorzystasz
get_code(dt, df.columns)
z tego samego przykładu, otrzymasz:źródło
(threshold[node] != -2)
na( left[node] != -1)
(podobnie do poniższej metody uzyskiwania identyfikatorów węzłów potomnych)Scikit Learn wprowadził nową, pyszną metodę o nazwie
export_text
0.21 (maj 2019) do wyodrębniania reguł z drzewa. Dokumentacja tutaj . Tworzenie funkcji niestandardowej nie jest już konieczne.Po dopasowaniu modelu potrzebujesz tylko dwóch wierszy kodu. Najpierw zaimportuj
export_text
:Po drugie, stwórz obiekt, który będzie zawierał twoje reguły. Aby reguły wyglądały bardziej czytelnie, użyj
feature_names
argumentu i przekaż listę nazw funkcji. Na przykład, jeśli twój model jest wywoływany,model
a twoje elementy są nazwane w wywołanej ramce danychX_train
, możesz utworzyć obiekt o nazwietree_rules
:Następnie po prostu wydrukuj lub zapisz
tree_rules
. Twój wynik będzie wyglądał następująco:źródło
Jest to nowa
DecisionTreeClassifier
metoda,decision_path
w 0.18.0 wydaniu. Deweloperzy zapewniają obszerny (dobrze udokumentowany) przewodnik .Pierwsza sekcja kodu w przewodniku, która drukuje strukturę drzewa, wydaje się być w porządku. Jednak zmodyfikowałem kod w drugiej sekcji, aby odpytać jedną próbkę. Moje zmiany oznaczono
# <--
Edytuj Zmiany oznaczone
# <--
w poniższym kodzie zostały od tego czasu zaktualizowane w łączu instruktażowym po wskazaniu błędów w żądaniach ściągnięcia # 8653 i # 10951 . O wiele łatwiej jest teraz śledzić.Zmień,
sample_id
aby zobaczyć ścieżki decyzyjne dla innych próbek. Nie pytałem programistów o te zmiany, po prostu wydawałem się bardziej intuicyjny podczas pracy z przykładem.źródło
Możesz zobaczyć drzewo dwuznaków. Następnie
clf.tree_.feature
iclf.tree_.value
są odpowiednio tablicą funkcji podziału węzłów i tablicą wartości węzłów. Możesz odnieść się do dalszych szczegółów z tego źródła na githubie .źródło
Tylko dlatego, że wszyscy byli tak pomocni, dodam tylko modyfikację do pięknych rozwiązań Zelazny7 i Daniele. Ten jest przeznaczony dla Pythona 2.7, z zakładkami, aby uczynić go bardziej czytelnym:
źródło
Kody poniżej to moje podejście w anaconda python 2.7 plus nazwa pakietu "pydot-ng" do tworzenia pliku PDF z regułami decyzyjnymi. Mam nadzieję, że jest to pomocne.
tutaj wykres drzewa
źródło
Przechodziłem przez to, ale potrzebowałem napisać zasady w tym formacie
Dlatego dostosowałem odpowiedź @paulkernfeld (dzięki), którą możesz dostosować do swoich potrzeb
źródło
Oto sposób na przetłumaczenie całego drzewa na pojedyncze (niekoniecznie zbyt czytelne dla człowieka) wyrażenie Pythona przy użyciu biblioteki SKompiler :
źródło
To opiera się na odpowiedzi @paulkernfeld. Jeśli masz ramkę danych X ze swoimi funkcjami i docelową ramkę danych y z twoimi rezonami i chcesz dowiedzieć się, która wartość y kończy się w którym węźle (a także odpowiednio ją wykreślić), możesz wykonać następujące czynności:
nie jest to najbardziej elegancka wersja, ale spełnia swoje zadanie ...
źródło
To jest kod, którego potrzebujesz
Zmodyfikowałem najpopularniejszy kod, aby poprawnie wciskać w pythonie 3 notebooka jupyter
źródło
Oto funkcja, wypisująca reguły drzewa decyzyjnego scikit-learn w Pythonie 3 i z przesunięciami dla bloków warunkowych, aby uczynić strukturę bardziej czytelną:
źródło
Możesz również uczynić go bardziej informacyjnym, rozróżniając go, do której klasy należy, lub nawet wymieniając jego wartość wyjściową.
źródło
Oto moje podejście do wyodrębniania reguł decyzyjnych w postaci, której można używać bezpośrednio w sql, dzięki czemu dane mogą być grupowane według węzłów. (Na podstawie podejść z poprzednich plakatów.)
Rezultatem będą kolejne
CASE
klauzule, które można skopiować do instrukcji sql, np.SELECT COALESCE(*CASE WHEN <conditions> THEN > <NodeA>*, > *CASE WHEN <conditions> THEN <NodeB>*, > ....)NodeName,* > FROM <table or view>
źródło
Teraz możesz użyć export_text.
Kompletny przykład z [sklearn] [1]
źródło
Zmodyfikowany kod Zelazny7 do pobierania SQL z drzewa decyzyjnego.
źródło
Najwyraźniej dawno temu ktoś już zdecydował się spróbować dodać następującą funkcję do oficjalnych funkcji eksportu drzewa scikita (która w zasadzie obsługuje tylko export_graphviz)
Oto jego pełne zobowiązanie:
https://github.com/scikit-learn/scikit-learn/blob/79bdc8f711d0af225ed6be9fdb708cea9f98a910/sklearn/tree/export.py
Nie jestem pewien, co się stało z tym komentarzem. Ale możesz też spróbować użyć tej funkcji.
Myślę, że to uzasadnia poważną prośbę o dokumentację do dobrych ludzi scikit-learn, aby właściwie udokumentować
sklearn.tree.Tree
API, które jest podstawową strukturą drzewa, któraDecisionTreeClassifier
ujawnia się jako jej atrybuttree_
.źródło
Po prostu użyj funkcji ze sklearn.tree w ten sposób
Następnie poszukaj w folderze projektu pliku tree.dot , skopiuj CAŁĄ zawartość i wklej ją tutaj http://www.webgraphviz.com/ i wygeneruj swój wykres :)
źródło
Dziękuję za wspaniałe rozwiązanie @paulkerfeld. Na szczycie jego rozwiązanie, dla wszystkich tych, którzy chcą mieć zserializowaną wersję drzew, wystarczy użyć
tree.threshold
,tree.children_left
,tree.children_right
,tree.feature
itree.value
. Ponieważ liście nie mają podziałów, a zatem nie mają nazw funkcji ani elementów potomnych, ich symbol zastępczy wtree.feature
itree.children_***
to_tree.TREE_UNDEFINED
i_tree.TREE_LEAF
. Każdemu podziałowi przypisywany jest unikalny indeksdepth first search
.Zauważ, że
tree.value
ma kształt[n, 1, 1]
źródło
Oto funkcja, która generuje kod Pythona z drzewa decyzyjnego poprzez konwersję danych wyjściowych
export_text
:Przykładowe użycie:
Przykładowe dane wyjściowe:
Powyższy przykład jest generowany za pomocą
names = ['f'+str(j+1) for j in range(NUM_FEATURES)]
.Jedną z przydatnych funkcji jest to, że może generować mniejszy rozmiar pliku ze zmniejszonymi odstępami. Po prostu ustaw
spacing=2
.źródło