Что делает `sample_weight` для того, чтобы "DecisionTreeClassifier" работал в sklearn?

Я прочитал из эту документацию, которая:

"Балансировка классов может быть выполнена путем выборки равного количества выборок из каждого класса или, предпочтительно, путем нормализации суммы весов выборки (sample_weight) для каждого класса с тем же значением".

Но мне все еще не ясно, как это работает. Если я установил sample_weight с массивом из двух возможных значений, 1 и 2 ', означает ли это, что образцы с 2 будут отбираться в два раза чаще, чем образцы с 1 при выполнении мешок? Я не могу придумать практический пример этого.

Ответ 1

Итак, я потратил немного времени на изучение источника sklearn, потому что на самом деле я хотел попытаться понять это сам и на некоторое время. Прошу прощения за длину, но я не знаю, как объяснить это более кратко.


Некоторые быстрые предварительные комментарии:

Скажем, у нас есть проблема классификации с К-классами. В области пространственного пространства, представленной node дерева решений, напомним, что "примесь" области измеряется путем количественной оценки неоднородности с использованием вероятности класса в этой области. Обычно мы оцениваем:

Pr(Class=k) = #(examples of class k in region) / #(total examples in region)

Мера примеси принимает в качестве входных данных массив вероятностей класса:

[Pr(Class=1), Pr(Class=2), ..., Pr(Class=K)]

и выплескивает число, которое говорит вам, как "нечисто" или как неоднородно по классу область пространства объектов. Например, мера gini для задачи двух классов: 2*p*(1-p), где p = Pr(Class=1) и 1-p=Pr(Class=2).


Теперь, в основном, короткий ответ на ваш вопрос:

sample_weight увеличивает оценки вероятности в массиве вероятностей..., который дополняет примесную меру... которая расширяет разделение узлов... что увеличивает количество деревьев., который увеличивает, как пространство объектов нарезается для классификации.

Я считаю, что это лучше всего иллюстрируется на примере.


Сначала рассмотрим следующую проблему 2-класса, где входы 1-мерные:

from sklearn.tree import DecisionTreeClassifier as DTC

X = [[0],[1],[2]] # 3 simple training examples
Y = [ 1,  2,  1 ] # class labels

dtc = DTC(max_depth=1)

Итак, мы будем смотреть деревья с помощью только root node и двух детей. Обратите внимание, что примесь по умолчанию измеряет меру gini.


Случай 1: нет sample_weight

dtc.fit(X,Y)
print dtc.tree_.threshold
# [0.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0, 0.5]

Первое значение в массиве threshold сообщает нам, что 1-й пример обучения отправляется левому дочернему элементу node, а второй и третий примеры обучения отправляются в правый дочерний элемент node. Последние два значения в threshold являются заполнителями и должны игнорироваться. Массив impurity сообщает нам вычисленные значения примесей в родительском, левом и правом узлах соответственно.

В родительском node, p = Pr(Class=1) = 2. / 3., так что gini = 2*(2.0/3.0)*(1.0/3.0) = 0.444..... Вы также можете подтвердить дочерние примеси node.


Случай 2: с sample_weight

Теперь попробуем:

dtc.fit(X,Y,sample_weight=[1,2,3])
print dtc.tree_.threshold
# [1.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0.44444444, 0.]

Вы можете видеть, что порог функции отличается. sample_weight также влияет на примесную меру в каждом node. В частности, в оценках вероятности первый пример обучения считается одним и тем же, второй считается двойным, а третий считается тройным из-за весов выборки, которые мы предоставили.

Примесь в родительской области node такая же. Это просто совпадение. Мы можем вычислить его напрямую:

p = Pr(Class=1) = (1+3) / (1+2+3) = 2.0/3.0

Далее следует показатель gini 4/9.

Теперь вы можете видеть из выбранного порога, что первый и второй примеры обучения отправляются левому дочернему элементу node, а третий отправляется вправо. Мы видим, что примесь вычисляется как 4/9 также в левом дочернем элементе node, потому что:

p = Pr(Class=1) = 1 / (1+2) = 1/3.

Примесь нуля в правом ребёнке обусловлена ​​только одним примером обучения, лежащим в этой области.

Вы можете расширить это с помощью нецелых выборочных масок аналогично. Я рекомендую попробовать что-то вроде sample_weight = [1,2,2.5] и подтвердить вычисленные примеси.

Надеюсь, это поможет!