不平衡分类的权重

Weights for unbalanced classification

我正在处理一个不平衡的 class化问题,其中目标变量包含:

np.bincount(y_train)
array([151953,  13273])

151953 个零和 13273 个。

为了解决这个问题,我在定义 DMatrix 时使用了 XGBoostweight 参数:

dtrain = xgb.DMatrix(data=X_train, 
                     label=y_train,
                     weight=weights)

对于我一直使用的权重:

bc = np.bincount(y_train)
n_samples = bc.sum()
n_classes = len(bc)
weights = n_samples / (n_classes * bc)
w = weights[y_train.values]

其中 weightsarray([0.54367469, 6.22413923]),最后一行代码我只是使用 y_train 中的二进制值对其进行索引。这似乎是定义权重的正确方法,因为它表示一个 class 与另一个的值的数量之间的实际比率。然而,这似乎有利于少数class,这可以通过检查混淆矩阵看出:

array([[18881, 19195],
       [  657,  2574]])

因此,通过尝试不同的权重值,我意识到在相当接近的权重比下,特别是 array([1, 7]),结果似乎更合理:

array([[23020, 15056],
       [  837,  2394]])

所以我的问题是:

在内部,xgboost 通过将计算出的梯度和粗麻布乘以权重 [ref],使用输入权重来提升来自少数 class 的样本对损失函数的贡献。

虽然有前途和流行,但没有证据表明您提到的方法会产生最佳性能(这还取决于其他超参数的设置方式、数据分布和使用的指标);这只是一种启发式方法。您可能也想使用 ROC-AUC 进行评估(因为 recommended by xgboost). Like most other hyper-parameters, a more systematic method of optimizing weights is grid search. Here 是一个实现。

看来您使用的是二元分类模型。对于二进制问题,XGBoost 有一个称为 scale_pos_weight 的超参数,它可以平衡正负 类 之间的比率。 根据文档,scale_pos_weight 的值由公式计算得出。

scale_pos_weight = sum(负实例) / sum(正实例)

这个参数也可以调整,因此您可以使用 GridSearchCV 等方法找出最佳参数。