Могу ли я извлечь базовые правила принятия решений (или «пути принятия решений») из обученного дерева в дереве решений в виде текстового списка?
Что-то вроде:
if A>0.4 then if B<0.2 then if C>0.8 then class='X'
Спасибо за вашу помощь.
python
machine-learning
scikit-learn
decision-tree
random-forest
Дрор Хилман
источник
источник
Ответы:
Я считаю, что этот ответ является более правильным, чем другие ответы здесь:
Это распечатывает допустимую функцию Python. Вот пример выходных данных для дерева, которое пытается вернуть свой ввод, число от 0 до 10.
Вот некоторые камни преткновения, которые я вижу в других ответах:
tree_.threshold == -2
чтобы решить, является ли узел листом, не является хорошей идеей. Что если это реальный узел принятия решения с порогом -2? Вместо этого вы должны посмотреть наtree.feature
илиtree.children_*
.features = [feature_names[i] for i in tree_.feature]
падает с моей версией sklearn, потому что некоторые значенияtree.tree_.feature
равны -2 (специально для конечных узлов).источник
print "{}return {}".format(indent, tree_.value[node])
следует изменитьprint "{}return {}".format(indent, np.argmax(tree_.value[node][0]))
на функцию, возвращающую индекс класса.RandomForestClassifier.estimators_
, но я не смог понять, как объединить результаты оценок.print "bla"
=>print("bla")
Я создал свою собственную функцию для извлечения правил из деревьев решений, созданных sklearn:
Эта функция сначала начинается с узлов (обозначается -1 в дочерних массивах), а затем рекурсивно находит родителей. Я называю это «родословной» узла. Попутно я беру значения, которые мне нужны для создания логики SAS if / then / else:
Наборы кортежей ниже содержат все, что мне нужно для создания операторов SAS if / then / else. Мне не нравится использовать
do
блоки в SAS, поэтому я создаю логику, описывающую весь путь узла. Единственное целое число после кортежей - это идентификатор терминального узла в пути. Все предыдущие кортежи объединяются, чтобы создать этот узел.источник
(0.5, 2.5]
. Деревья сделаны с рекурсивным разбиением. Ничто не мешает выбрать переменную несколько раз.Я изменил код, представленный Zelazny7, чтобы напечатать некоторый псевдокод:
если ты позвонишь
get_code(dt, df.columns)
к тому же примеру, вы получите:источник
(threshold[node] != -2)
его( left[node] != -1)
(аналогично методу ниже для получения идентификаторов дочерних узлов)Scikit learn представил восхитительный новый метод, названный
export_text
в версии 0.21 (май 2019 г.) для извлечения правил из дерева. Документация здесь . Больше нет необходимости создавать пользовательские функции.После того, как вы подобрали свою модель, вам просто нужно две строки кода. Во-первых, импорт
export_text
:Во-вторых, создайте объект, который будет содержать ваши правила. Чтобы правила выглядели более читабельными, используйте
feature_names
аргумент и передайте список имен ваших объектов. Например, если ваша модель вызывается,model
а ваши функции называются в кадре данныхX_train
, вы можете создать объект с именемtree_rules
:Затем просто распечатайте или сохраните
tree_rules
. Ваш вывод будет выглядеть так:источник
Существует новый
DecisionTreeClassifier
метод,decision_path
в 0.18.0 релизе. Разработчики предоставляют обширный (хорошо задокументированный) обзор .Первый раздел кода в пошаговом руководстве, который печатает древовидную структуру, выглядит нормально. Однако я изменил код во втором разделе, чтобы опросить один образец. Мои изменения обозначены
# <--
Редактировать Изменения, отмеченные
# <--
в приведенном ниже коде, с тех пор были обновлены в пошаговой ссылке после того, как ошибки были указаны в запросах на получение доступа # 8653 и # 10951 . Теперь намного легче следовать за ним.Измените,
sample_id
чтобы увидеть пути решения для других образцов. Я не спрашивал разработчиков об этих изменениях, просто казался более интуитивным при работе с примером.источник
Вы можете увидеть дерево орграфа. Тогда,
clf.tree_.feature
иclf.tree_.value
являются массивом узлов, разделяющим признак и массивом значений узлов соответственно. Вы можете обратиться к более подробной информации из этого источника GitHub .источник
Просто потому, что все были так полезны, я просто добавлю модификацию в прекрасные решения Zelazny7 и Даниэле. Это для Python 2.7, с вкладками, чтобы сделать его более читабельным:
источник
Коды ниже - это мой подход под anaconda python 2.7 плюс имя пакета "pydot-ng" для создания файла PDF с правилами принятия решений. Я надеюсь, что это полезно.
дерево графическое шоу здесь
источник
Я проходил через это, но мне нужно, чтобы правила были написаны в этом формате
Поэтому я адаптировал ответ @paulkernfeld (спасибо), который вы можете настроить под свои нужды
источник
Вот способ перевести все дерево в одно (не обязательно слишком удобочитаемое) выражение python с помощью библиотеки SKompiler :
источник
Это основано на ответе @paulkernfeld. Если у вас есть фрейм данных X с вашими функциями и целевой фрейм данных y с вашими резонансами, и вы хотите получить представление о том, какое значение y заканчивается в каком узле (а также ant для его построения соответственно), вы можете сделать следующее:
не самая элегантная версия, но она делает свою работу ...
источник
Это код, который вам нужен
Я изменил самый популярный код, чтобы сделать отступ в jupyter notebook python 3 правильно
источник
Вот функция, печатающая правила дерева решений scikit-learn под python 3 и со смещениями для условных блоков, чтобы сделать структуру более читабельной:
источник
Вы также можете сделать его более информативным, выделив его, к какому классу он принадлежит, или даже упомянув его выходное значение.
источник
Вот мой подход к извлечению правил принятия решений в форме, которую можно использовать непосредственно в SQL, чтобы данные можно было сгруппировать по узлам. (На основе подходов предыдущих постеров.)
Результатом будут последующие
CASE
предложения, которые можно скопировать в оператор SQL, напр.SELECT COALESCE(*CASE WHEN <conditions> THEN > <NodeA>*, > *CASE WHEN <conditions> THEN <NodeB>*, > ....)NodeName,* > FROM <table or view>
источник
Теперь вы можете использовать export_text.
Полный пример из [sklearn] [1]
источник
Изменен код Zelazny7 для извлечения SQL из дерева решений.
источник
Видимо, давно кто-то уже решил попробовать добавить следующую функцию в функции экспорта дерева официального scikit (который в основном поддерживает только export_graphviz)
Вот его полный коммит:
https://github.com/scikit-learn/scikit-learn/blob/79bdc8f711d0af225ed6be9fdb708cea9f98a910/sklearn/tree/export.py
Не совсем уверен, что случилось с этим комментарием. Но вы также можете попробовать использовать эту функцию.
Я думаю, что это требует серьезного запроса на документацию для хороших людей scikit-learn, чтобы правильно документировать
sklearn.tree.Tree
API, который является базовой структурой дерева, котораяDecisionTreeClassifier
выставляется как его атрибутtree_
.источник
Просто используйте функцию из sklearn.tree, как это
А затем найдите в папке вашего проекта файл tree.dot , скопируйте ВСЕ содержимое и вставьте его сюда http://www.webgraphviz.com/ и сгенерируйте свой график :)
источник
Спасибо за замечательное решение @paulkerfeld. На вершине своего решения, для всех тех , кто хочет иметь упорядоченную версию дерев, просто использовать
tree.threshold
,tree.children_left
,tree.children_right
,tree.feature
иtree.value
. Так как листья не имеют разбиений и, следовательно, не имеют имен элементов и дочерних элементов, их заполнители вtree.feature
иtree.children_***
являются_tree.TREE_UNDEFINED
и_tree.TREE_LEAF
. Каждому разделению присваивается уникальный индексdepth first search
.Обратите внимание, что
tree.value
форма[n, 1, 1]
источник
Вот функция, которая генерирует код Python из дерева решений путем преобразования вывода
export_text
:Пример использования:
Пример вывода:
Приведенный выше пример генерируется с
names = ['f'+str(j+1) for j in range(NUM_FEATURES)]
.Одна удобная особенность заключается в том, что он может генерировать файлы меньшего размера с уменьшенным интервалом. Просто установите
spacing=2
.источник