使用 XGBoost 的不平衡多类数据

数据挖掘 分类 xgboost 多类分类 阶级失衡
2021-10-04 21:36:15

我有 3 个具有此分布的课程:

Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163

我正在使用xgboost分类。我知道有一个参数叫做scale_pos_weight.

但是如何处理“多类”案例,如何正确设置它?

4个回答

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

sum(negative instances) / sum(positive instances)

对于您的特定情况,还有另一种选择,以便在使用助推器时对单个数据点进行加权并考虑它们的权重,并对其权重进行优化,以便每个点均等表示。您只需要简单地使用:

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

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

@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

对于 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)

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

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

谢谢蜡笔