不平衡分类的权重
Weights for unbalanced classification
我正在处理一个不平衡的 class化问题,其中目标变量包含:
np.bincount(y_train)
array([151953, 13273])
即151953
个零和 13273
个。
为了解决这个问题,我在定义 DMatrix 时使用了 XGBoost
的 weight
参数:
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]
其中 weights
是 array([0.54367469, 6.22413923])
,最后一行代码我只是使用 y_train
中的二进制值对其进行索引。这似乎是定义权重的正确方法,因为它表示一个 class 与另一个的值的数量之间的实际比率。然而,这似乎有利于少数class,这可以通过检查混淆矩阵看出:
array([[18881, 19195],
[ 657, 2574]])
因此,通过尝试不同的权重值,我意识到在相当接近的权重比下,特别是 array([1, 7])
,结果似乎更合理:
array([[23020, 15056],
[ 837, 2394]])
所以我的问题是:
- 为什么使用每个 class 的实际权重会产生糟糕的指标?
- 为不平衡问题设置权重的正确方法是什么?
在内部,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 等方法找出最佳参数。
我正在处理一个不平衡的 class化问题,其中目标变量包含:
np.bincount(y_train)
array([151953, 13273])
即151953
个零和 13273
个。
为了解决这个问题,我在定义 DMatrix 时使用了 XGBoost
的 weight
参数:
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]
其中 weights
是 array([0.54367469, 6.22413923])
,最后一行代码我只是使用 y_train
中的二进制值对其进行索引。这似乎是定义权重的正确方法,因为它表示一个 class 与另一个的值的数量之间的实际比率。然而,这似乎有利于少数class,这可以通过检查混淆矩阵看出:
array([[18881, 19195],
[ 657, 2574]])
因此,通过尝试不同的权重值,我意识到在相当接近的权重比下,特别是 array([1, 7])
,结果似乎更合理:
array([[23020, 15056],
[ 837, 2394]])
所以我的问题是:
- 为什么使用每个 class 的实际权重会产生糟糕的指标?
- 为不平衡问题设置权重的正确方法是什么?
在内部,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 等方法找出最佳参数。