`sample_weight` 对 `DecisionTreeClassifier` 在 sklearn 中的工作方式做了什么?
What does `sample_weight` do to the way a `DecisionTreeClassifier` works in sklearn?
我从 relevant documentation 中读到:
Class balancing can be done by sampling an equal number of samples from each class, or preferably by normalizing the sum of the sample weights (sample_weight
) for each class to the same value.
但是,我仍然不清楚这是如何工作的。如果我将 sample_weight
设置为仅包含两个可能值的数组,即 1
和 2
,这是否意味着将对具有 2
的样本进行采样进行装袋时,频率是 1
样本的两倍?我想不出一个实际的例子。
一些快速准备:
假设我们有 K classes 的 class化问题。在由决策树节点表示的特征 space 区域中,回想一下该区域的“不纯度”是通过使用该区域中 class 的概率量化不均匀性来衡量的。通常,我们估计:
Pr(Class=k) = #(examples of class k in region) / #(total examples in region)
杂质度量作为输入,class 概率数组:
[Pr(Class=1), Pr(Class=2), ..., Pr(Class=K)]
并吐出一个数字,告诉您 inhomogeneous-by-class 特征区域 space 有多“不纯”。例如,两个 class 问题的基尼系数是 2*p*(1-p)
,其中 p = Pr(Class=1)
和 1-p=Pr(Class=2)
.
现在,基本上对你的问题的简短回答是:
sample_weight
增加了概率数组中的概率估计 ...这增加了杂质度量...这增加了节点的分裂方式...这增加了树是如何构建的...这增加了特征 space 是如何被分割成 classification.
我认为最好通过示例来说明这一点。
首先考虑以下输入为一维的 2-class 问题:
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)
因此,我们将查看只有一个根节点和两个 children 的树。请注意,默认的不纯度衡量基尼系数。
情况一:没有sample_weight
dtc.fit(X,Y)
print dtc.tree_.threshold
# [0.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0, 0.5]
threshold
数组中的第一个值告诉我们第一个训练样例被发送到左侧child节点,第二个和第三个训练样例被发送到右侧[=81] =] 节点。 threshold
中的最后两个值是占位符,将被忽略。 impurity
数组告诉我们分别在 parent、左和右节点中计算出的杂质值。
在parent节点中,p = Pr(Class=1) = 2. / 3.
,所以gini = 2*(2.0/3.0)*(1.0/3.0) = 0.444....
。您也可以确认 child 节点杂质。
案例 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
还会影响每个节点中的杂质度量。具体来说,在概率估计中,由于我们提供的样本权重,第一个训练示例被计算为相同,第二个被计算为两倍,第三个被计算为三倍。
parent节点区域的杂质是一样的。这只是一个巧合。我们可以直接计算:
p = Pr(Class=1) = (1+3) / (1+2+3) = 2.0/3.0
4/9
的基尼系数如下。
现在,您可以从选择的阈值中看出,第一个和第二个训练示例被发送到左侧 child 节点,而第三个被发送到右侧。我们看到杂质在左侧 child 节点中也被计算为 4/9
因为:
p = Pr(Class=1) = 1 / (1+2) = 1/3.
右侧 child 的零杂质是由于该区域只有一个训练样本。
您可以用 non-integer sample-wights 类似地扩展它。我建议尝试 sample_weight = [1,2,2.5]
之类的方法,并确认计算出的杂质。
我从 relevant documentation 中读到:
Class balancing can be done by sampling an equal number of samples from each class, or preferably by normalizing the sum of the sample weights (
sample_weight
) for each class to the same value.
但是,我仍然不清楚这是如何工作的。如果我将 sample_weight
设置为仅包含两个可能值的数组,即 1
和 2
,这是否意味着将对具有 2
的样本进行采样进行装袋时,频率是 1
样本的两倍?我想不出一个实际的例子。
一些快速准备:
假设我们有 K classes 的 class化问题。在由决策树节点表示的特征 space 区域中,回想一下该区域的“不纯度”是通过使用该区域中 class 的概率量化不均匀性来衡量的。通常,我们估计:
Pr(Class=k) = #(examples of class k in region) / #(total examples in region)
杂质度量作为输入,class 概率数组:
[Pr(Class=1), Pr(Class=2), ..., Pr(Class=K)]
并吐出一个数字,告诉您 inhomogeneous-by-class 特征区域 space 有多“不纯”。例如,两个 class 问题的基尼系数是 2*p*(1-p)
,其中 p = Pr(Class=1)
和 1-p=Pr(Class=2)
.
现在,基本上对你的问题的简短回答是:
sample_weight
增加了概率数组中的概率估计 ...这增加了杂质度量...这增加了节点的分裂方式...这增加了树是如何构建的...这增加了特征 space 是如何被分割成 classification.
我认为最好通过示例来说明这一点。
首先考虑以下输入为一维的 2-class 问题:
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)
因此,我们将查看只有一个根节点和两个 children 的树。请注意,默认的不纯度衡量基尼系数。
情况一:没有sample_weight
dtc.fit(X,Y)
print dtc.tree_.threshold
# [0.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0, 0.5]
threshold
数组中的第一个值告诉我们第一个训练样例被发送到左侧child节点,第二个和第三个训练样例被发送到右侧[=81] =] 节点。 threshold
中的最后两个值是占位符,将被忽略。 impurity
数组告诉我们分别在 parent、左和右节点中计算出的杂质值。
在parent节点中,p = Pr(Class=1) = 2. / 3.
,所以gini = 2*(2.0/3.0)*(1.0/3.0) = 0.444....
。您也可以确认 child 节点杂质。
案例 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
还会影响每个节点中的杂质度量。具体来说,在概率估计中,由于我们提供的样本权重,第一个训练示例被计算为相同,第二个被计算为两倍,第三个被计算为三倍。
parent节点区域的杂质是一样的。这只是一个巧合。我们可以直接计算:
p = Pr(Class=1) = (1+3) / (1+2+3) = 2.0/3.0
4/9
的基尼系数如下。
现在,您可以从选择的阈值中看出,第一个和第二个训练示例被发送到左侧 child 节点,而第三个被发送到右侧。我们看到杂质在左侧 child 节点中也被计算为 4/9
因为:
p = Pr(Class=1) = 1 / (1+2) = 1/3.
右侧 child 的零杂质是由于该区域只有一个训练样本。
您可以用 non-integer sample-wights 类似地扩展它。我建议尝试 sample_weight = [1,2,2.5]
之类的方法,并确认计算出的杂质。