Деревья решений и списки решений — два популярных языка гипотез, которые имеют немало общего. Ключевое отличие состоит в том, что деревья решений можно рассматривать как неупорядоченные наборы правил, где каждый лист дерева соответствует одному правилу с частью условия, состоящей из соединения всех меток ребер на пути от корня к этому листу. Иерархическая структура дерева гарантирует, что правила в наборе не перекрываются, то есть каждый пример может быть покрыт только одним правилом. Это дополнительное ограничение упрощает классификацию (отсутствие конфликтов из-за нескольких правил), но может привести к более сложным правилам. Например, было показано, что списки решений (упорядоченные наборы правил) с не более чем k условиями на правило строго более выразительны, чем деревья решений глубины k.Более того, ограничение алгоритмов обучения дерева решений непересекающимися правилами накладывает сильные ограничения.
========================
Список решений (также называемый упорядоченным набором правил) представляет собой набор отдельных правил классификации, которые в совокупности образуют классификатор. В отличие от неупорядоченного набора правил, списки решений имеют неотъемлемый порядок, что делает классификацию довольно простой. Для классификации нового экземпляра правила проверяются по порядку, и прогнозируется класс первого правила, которое охватывает экземпляр. Если не срабатывает индуцированное правило, вызывается правило по умолчанию, которое обычно предсказывает класс большинства.
(.env) boris@boris-All-Series:~/DecisionTree$ cat ConvertionDTree.py
from matplotlib import pyplot as plt
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
from sklearn import tree
import numpy as np
# Prepare the data data
iris = datasets.load_iris()
X = iris.data
y = iris.target
# Fit the classifier with max_depth=3
clf = DecisionTreeClassifier(max_depth=3, random_state=1234)
model = clf.fit(X, y)
text_representation = tree.export_text(clf, feature_names=iris.feature_names)
print(text_representation)
print('Decision Tree has been built','\n')
from sklearn.tree import _tree
def get_rules(tree, feature_names, class_names):
tree_ = tree.tree_
feature_name = [
feature_names[i] if i != _tree.TREE_UNDEFINED else "undefined!"
for i in tree_.feature
]
paths = []
path = []
def recurse(node, path, paths):
if tree_.feature[node] != _tree.TREE_UNDEFINED:
name = feature_name[node]
threshold = tree_.threshold[node]
p1, p2 = list(path), list(path)
p1 += [f"({name} <= {np.round(threshold, 3)})"]
recurse(tree_.children_left[node], p1, paths)
p2 += [f"({name} > {np.round(threshold, 3)})"]
recurse(tree_.children_right[node], p2, paths)
else:
path += [(tree_.value[node], tree_.n_node_samples[node])]
paths += [path]
recurse(0, path, paths)
# sort by samples count
samples_count = [p[-1][1] for p in paths]
ii = list(np.argsort(samples_count))
paths = [paths[i] for i in reversed(ii)]
rules = []
for path in paths:
rule = "if "
for p in path[:-1]:
if rule != "if ":
rule += " and "
rule += str(p)
rule += " then "
if class_names is None:
rule += "response: "+str(np.round(path[-1][0][0][0],3))
else:
classes = path[-1][0][0]
l = np.argmax(classes)
rule += f"class: {class_names[l]} (proba: {np.round(100.0*classes[l]/np.sum(classes),2)}%)"
rule += f" | based on {path[-1][1]:,} samples"
rules += [rule]
return rules
rules = get_rules(clf, iris.feature_names, iris.target_names)
for r in rules:
print(r)
(.env) boris@boris-All-Series:~/DecisionTree$ python3 ConvertionDTree.py
|--- petal length (cm) <= 2.45
| |--- class: 0
|--- petal length (cm) > 2.45
| |--- petal width (cm) <= 1.75
| | |--- petal length (cm) <= 4.95
| | | |--- class: 1
| | |--- petal length (cm) > 4.95
| | | |--- class: 2
| |--- petal width (cm) > 1.75
| | |--- petal length (cm) <= 4.85
| | | |--- class: 2
| | |--- petal length (cm) > 4.85
| | | |--- class: 2
Decision Tree has been built
if (petal length (cm) <= 2.45) then class: setosa (proba: 100.0%) | based on 50 samples
if (petal length (cm) > 2.45) and (petal width (cm) <= 1.75) and (petal length (cm) <= 4.95) then class: versicolor (proba: 97.92%) | based on 48 samples
if (petal length (cm) > 2.45) and (petal width (cm) > 1.75) and (petal length (cm) > 4.85) then class: virginica (proba: 100.0%) | based on 43 samples
if (petal length (cm) > 2.45) and (petal width (cm) <= 1.75) and (petal length (cm) > 4.95) then class: virginica (proba: 66.67%) | based on 6 samples
if (petal length (cm) > 2.45) and (petal width (cm) > 1.75) and (petal length (cm) <= 4.85) then class: virginica (proba: 66.67%) | based on 3 samples
No comments:
Post a Comment