CatBoost 精度不平衡类

Ale*_*aev 5 machine-learning scikit-learn catboost

我使用 CatBoostClassifier,我的类高度不平衡。我应用了一个scale_pos_weight参数来解决这个问题。在使用评估数据集(测试)进行训练时,CatBoost 在测试中显示出很高的精度。然而,当我使用预测方法对测试进行预测时,我只得到低精度分数(使用 sklearn.metrics 计算)。

我认为这可能与我应用的班级权重有关。但是,我不太明白精度分数是如何受此影响的。

params = frozendict({
    'task_type': 'CPU',
    'loss_function': 'Logloss',
    'eval_metric': 'F1', 
    'custom_metric': ['F1', 'Precision', 'Recall'],
    'iterations': 100,
    'random_seed': 20190128,
    'scale_pos_weight': 56.88657244809081,
    'learning_rate': 0.5412829495147387, 
    'depth': 7, 
    'l2_leaf_reg': 9.526905230698302
})

from catboost import CatBoostClassifier
model = cb.CatBoostClassifier(**params)
model.fit(
    X_train, y_train,
    cat_features=np.where(X_train.dtypes == np.object)[0],
    eval_set=(X_test, y_test),
    verbose=False,
    plot=True
)

model.get_best_score()
{'learn': {'Recall': 0.9243007537531925,
  'Logloss': 0.15892360013680026,
  'F1': 0.9416723809244181,
  'Precision': 0.9640191600545249},
 'validation_0': {'Recall': 0.914252301192093,
  'Logloss': 0.1714387314107052,
  'F1': 0.9357892623978286,
  'Precision': 0.9642642597943112}}

y_test_pred = model.predict(data=X_test)

from sklearn.metrics import balanced_accuracy_score, recall_score, precision_score, f1_score
print('Balanced accuracy: {:.2f}'.format(balanced_accuracy_score(y_test, y_test_pred)))
print('Precision: {:.2f}'.format(precision_score(y_test, y_test_pred)))
print('Recall: {:.2f}'.format(recall_score(y_test, y_test_pred)))
print('F1: {:.2f}'.format(f1_score(y_test, y_test_pred)))

Balanced accuracy: 0.94
Precision: 0.29
Recall: 0.91
F1: 0.44
Run Code Online (Sandbox Code Playgroud)

我期望在训练时获得与 CatBoost 相同的精度,但事实并非如此。我究竟做错了什么?

小智 5

默认use_weights设置为True,表示给评价指标添加权重,例如Precision:use_weights=True,为了让自己的精度计算器和他的一样,改成 Precision:use_weights=False

此外,get_best_score在迭代中给出最高分数,您需要指定在预测中使用哪个迭代。您可以设置use_best_model=True自动model.fit选择迭代。


小智 3

预测函数使用标准阈值 0.5 将预测的概率转换为二进制值。当您处理不平衡问题时,0.5 的阈值并不总是最佳值,这就是您在测试集上获得较差精度的原因。

为了找到更好的阈值,catboost 有一些方法可以帮助您做到这一点,例如 get_roc_curve、get_fpr_curve、get_fnr_curve。这 3 种方法可以帮助您通过更改预测阈值来可视化真阳性率、假阳性率和假阴性率。

除了这些可视化方法之外,catboost 还有一种名为 select_threshold 的方法,它可以通过优化其中一条曲线来为您提供最佳阈值。

您可以在他们的文档中查看这一点。