Как интерпретировать (неожиданные) значения атрибута sklearn.tree.tree_tree.value? - PullRequest
0 голосов
/ 10 января 2019

Значения атрибута значения, соответствующего заглушкам классификатора дерева решений, используемым с AdaBoostClassifier, не соответствуют ожиданиям, и я не могу определить, какие значения указывают. Я хотел бы понять значения, помогающие проанализировать поведение оценщика заглушки и тот вклад, который заглушки вносят в AdaBoostClassifier. Подобные вопросы к Stackoverflow не коррелируют с моими данными.

Информация о версии

  • питон: 3.6.5
  • sklearn версия: 0.20.2

Заглушки DecisionTreeClassifier сконфигурированы как:

number_estimators = 301
bdt= AdaBoostClassifier(DecisionTreeClassifier(max_depth=1), 
algorithm="SAMME.R", n_estimators=number_estimators)

AdaBoostClassifier - это двоичный классификатор с выходными состояниями Class A и Class B (кодируется как +1 и -1). Тренировочный набор состоит из 23 функций, и классификатор работает нормально (точность прогноза, точность, вспомните все примерно 79%). Я анализирую пропущенные прогнозы, чтобы получить представление об ошибках классификации.

Есть 782 учебных образца. Оценка 301 заглушки получена из AdaBoostClassifier через:

tree_stubs = bdt.estimators_

Пример заглушки, соответствующий 6-й оценке (список на основе 0):

bdt.estimators_[5]
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=1,
        max_features=None, max_leaf_nodes=None,
        min_impurity_decrease=0.0, min_impurity_split=None,
        min_samples_leaf=1, min_samples_split=2,
        min_weight_fraction_leaf=0.0, presort=False,
        random_state=421257592, splitter='best')

Значения для этой заглушки:

stub_5.tree_.value
array([[[0.5       , 0.5       ]],
   [[0.29308331, 0.1861591 ]],
   [[0.20691669, 0.3138409 ]]])       

Для тех, кто знаком с графвизом, заглушка дерева выглядит так:

tree stub

Корневой узел правильно отображает количество выборок (782). Атрибут значения указывает [0,5, 0,5]. Я ожидал, что атрибут value будет числом выборок в каждом классе, а не процентом. Но в корневом узле значения 0,5 отражают сбалансированный обучающий набор, который у меня есть, с равным представлением двух классов.

Теперь о проблеме. Функция разделения в этой заглушке делит выборки на основе значения delta_win_pct, которое меньше или равно пороговому значению -.001. Мой набор данных действительно имеет 385 выборочных записей, где delta_win_pct меньше этого порога, и 397 выборок, где delta_win_pct больше порога. Таким образом, данные образцов верны в левом и правом листовых узлах заглушки дерева.

Но данные значения кажутся неверными. В левом дочернем узле значения отображаются как значение = [0,293, 0,186], а в правом дочернем узле значение = [0,207, 0,314]. Обратите внимание, что это данные, сообщаемые классом sklearn.tree._tee.Tree, и они не указывают на какие-либо проблемы с graphviz.

Что представляют собой эти значения?

Учитывая левый конечный узел, мой набор данных на самом деле содержит 264 выборки класса A, у которых delta_win_pct <= -0.001 и 121 выборка класса B, соответствующих этому порогу разделения. Эти цифры соответствуют процентам от [.6857, .3143], а не [0,293, 0,186]. Неправильные значения не масштабируются линейно до ожидаемых значений. </p>

Аналогично для правого дочернего узла данные значений предоставляются как [0,207, 0,314], но ожидаемые значения должны быть [.330, .670] для 397 выборок, у которых delta_win_pct превышает пороговое значение.

Я замечаю, что числа в предоставленных данных значения (0,293, 0,186, 0,207, 0,314) складываются до 1,0. Но значения не складываются до 1,0 для каждого узла. Я попытался использовать предоставленные значения в процентах от всех образцов, например, 0,293 * 782 = 229, что ни с чем не связано.

Кто-нибудь знает, что означают данные предоставленной стоимости? Является ли моя интерпретация и ожидание этих значений неправильными?

Наконец, я замечаю, что относительная величина значений в данных правильно коррелирует с большинством выборок в каждом узле. В левом дочернем узле 0,293 больше 0,186, что указывает на то, что левый узел имеет большинство выборок класса А. В то время как в правом листовом узле 0,207 <0,314 указывает большинство выборок класса B, когда delta_win_pct> пороговое значение. Я подозреваю, что именно поэтому AdaBoostClassifier работает.

В любом случае, я бы хотел понять эти значения.

1 Ответ

0 голосов
/ 11 января 2019

Я попытался воспроизвести его в сгенерированном наборе данных:

import pydot 
import numpy as np
from IPython.display import Image, display
from sklearn.externals.six import StringIO  
from sklearn.tree import DecisionTreeClassifier,  _tree
from sklearn.datasets import make_classification
from sklearn.ensemble import AdaBoostClassifier


X, y = make_classification(n_informative=2, n_features=3, n_samples=200, n_redundant=1, random_state=42, n_classes=2)
feature_names = ['X0','X1','X2','X3']
clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1), 
algorithm="SAMME.R", n_estimators=301)
clf.fit(X, y)

estimator = clf.estimators_[0]
dot_data = StringIO() 
tree.export_graphviz(estimator, out_file=dot_data, proportion=False, filled=True,node_ids=True,rounded=True,class_names=['0','1']) 
graph = pydot.graph_from_dot_data(dot_data.getvalue()) [0]

def viewPydot(pdot):
    plt = Image(pdot.create_png())
    display(plt)
viewPydot(graph)

Я обнаружил, что есть два случая, "правильный" (clf.estimators_[0]), который выглядит следующим образом enter image description here

Здесь value обозначает долю определенного класса в узле относительно общего количества выборок, поэтому узел № 1: [84/200=0.42,7/200=0.035], узел № 2: [16/200=0.08,93/200=0.465]

Если вы установите для параметра proportion значение True, вы получите распределение классов для каждого узла в процентах, например, для узла № 2: [16/109, 93/109]=[0.147, 0.853]. рассчитывается с использованием атрибута weighted_n_node_samples, который в собственном случае равен количеству выборок для узла, деленному на общее количество выборок, например, 109/200 = 0,545, [0.08, 0.465]/0.545=[0.147, 0.853]

Другой случай (clf.estimators_[4]) - тот, с которым вы столкнулись:

enter image description here

Классы левого узла: [74, 7]

Классы узлов Rignt: [93, 26]

Распределение классов здесь не коррелирует с value, левый узел даже предсказывает класс меньшинства. Кажется, единственным подходящим случаем является первая оценка, у других есть эта проблема, может быть, это часть процедуры повышения? Кроме того, если вы возьмете любое дерево оценки и подгоните его вручную, вы получите те же числа, что и в первом, например,

>>> DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=1,
            max_features=None, max_leaf_nodes=None,
            min_impurity_decrease=0.0, min_impurity_split=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, presort=False,
            random_state=441365315, splitter='best').fit(X,y).tree_.value
array([[[100., 100.]],

       [[ 84.,   7.]],

       [[ 16.,  93.]]])
...