我有 3 个具有此分布的课程:
Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163
我正在使用xgboost
分类。我知道有一个参数叫做scale_pos_weight
.
但是如何处理“多类”案例,如何正确设置它?
我有 3 个具有此分布的课程:
Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163
我正在使用xgboost
分类。我知道有一个参数叫做scale_pos_weight
.
但是如何处理“多类”案例,如何正确设置它?
scale_pos_weight
如您所述,用于二进制分类。这是处理不平衡类的更通用的解决方案。分配值时的一个好方法scale_pos_weight
是:
sum(negative instances) / sum(positive instances)
对于您的特定情况,还有另一种选择,以便在使用助推器时对单个数据点进行加权并考虑它们的权重,并对其权重进行优化,以便每个点均等表示。您只需要简单地使用:
xgboost.DMatrix(..., weight = *weight array for individual weights*)
您可以根据需要定义权重,通过这样做,您甚至可以处理类内的不平衡以及不同类之间的不平衡。
@KeremT 的这个答案是正确的。我为那些对确切实施仍有问题的人提供了一个例子。
weight
XGBoost 中的参数是每个实例而不是每个类。因此,我们需要将每个类的权重分配给它的实例,这是同样的事情。
例如,如果我们有三个比例不平衡的类
class A = 10%
class B = 30%
class C = 60%
他们的权重是(将最小的类别除以其他类别)
class A = 1.000
class B = 0.333
class C = 0.167
那么,如果训练数据是
index class
0 A
1 A
2 B
3 C
4 B
我们构建weight
向量如下:
index class weight
0 A 1.000
1 A 1.000
2 B 0.333
3 C 0.167
4 B 0.333
对于 sklearn 版本 < 0.19
只需为您的火车数据的每个条目分配其类别权重。首先使用 sklearn 获取类权重,class_weight.compute_class_weight
然后为每一行训练数据分配适当的权重。
我在这里假设火车数据具有class
包含类号的列。我还假设有nb_classes
从 1 到nb_classes
.
from sklearn.utils import class_weight
classes_weights = list(class_weight.compute_class_weight('balanced',
np.unique(train_df['class']),
train_df['class']))
weights = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
weights[i] = classes_weights[val-1]
xgb_classifier.fit(X, y, sample_weight=weights)
更新 sklearn 版本 >= 0.19
有更简单的解决方案
from sklearn.utils import class_weight
classes_weights = class_weight.compute_sample_weight(
class_weight='balanced',
y=train_df['class']
)
xgb_classifier.fit(X, y, sample_weight=classes_weights)