使用XGBoost的不平衡多类数据


Answers:


18

scale_pos_weight如您所述,用于二进制分类。它是处理不平衡类的更通用的解决方案。将值分配给一个好方法scale_pos_weight是:

sum(negative instances) / sum(positive instances)

对于您的特定情况,还有另一个选项可以对单个数据点加权,并在使用增强器时考虑它们的权重,并让它们的权重发生优化,以便每个点均等地表示。您只需要简单地使用:

xgboost.DMatrix(..., weight = *weight array for individual weights*)

您可以根据需要定义权重,这样甚至可以处理类之间的不平衡以及不同类之间的不平衡。


>为scale_pos_weight分配值时的一种好方法是:sum(负实例)/ sum(正实例)
lcrmorin

1
我到处都可以看到这个建议,将较高的权重分配给代表较少的班级是有意义的。但是,我很难找到讨论此确切值的资料。我得到了该特定值(使样本平衡)背后的直觉,但我怀疑在某处存在方差折衷,这会使您希望考虑减轻重量。
lcrmorin

7

@KeremT的答案是正确的。我为那些仍然在确切实现方面仍存在问题的人提供了一个示例。

weightXGBoost中的参数不是每个类的实例。因此,我们需要将每个类的权重分配给它的实例,这是同一件事。

例如,如果我们有三个比率不平衡的类

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

5

在R中使用XGBoost处理不平衡的多类分类问题时,每个人都偶然发现了这个问题。我也做到了!

我正在寻找一个示例,以更好地了解如何应用它。投资了将近一个小时才能找到下面提到的链接。对于所有正在寻找示例的人,这里都有-

/datascience//a/9493/37156

谢谢wacax


1

只需为其火车数据的每个实例分配其班级权重即可。首先使用class_weight.compute_class_weightsklearn 获得班级权重,然后为火车数据的每一行分配适当的权重。

我在这里假设火车数据具有包含类号的“类”列。我还假设存在从1到nb_classes的nb_classes。

from sklearn.utils import class_weight
class_weights = list(class_weight.compute_class_weight('balanced',
                                             np.unique(train['class']),
                                             train['class']))

w_array = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
    w_array[i] = class_weights[val-1]

xgb_classifier.fit(X, y, sample_weight=w_array)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.