我使用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
我希望在训练时获得与 CatBoost 节目相同的精度,但事实并非如此。我做错了什么?
默认use_weights
设置为 True
,这意味着向评估指标添加权重,例如 Precision:use_weights=True
,要让您自己的精度计算器与他的计算器相同,请更改为精度:use_weights=False
此外,get_best_score
在迭代中给出最高分数,则需要指定要在预测中使用的迭代。您可以在model.fit
中设置use_best_model=True
以自动选择迭代。
预测函数使用标准阈值 0.5 将预测的概率转换为二进制值。当你处理一个不平衡的问题时,阈值0.5并不总是最好的值,这就是为什么在测试集上你达到的精度很差。
为了找到更好的阈值,catboost 有一些方法可以帮助您做到这一点,例如get_roc_curve、get_fpr_curve get_fnr_curve。这 3 种方法可以帮助您通过更改预测量来可视化真阳性、假阳性和假阴性率。
除了这些可视化方法之外,catboost 还有一种称为 select_threshold 的方法,它通过优化其中一条曲线为您提供最佳阈值。
您可以在他们的文档中查看这一点。
除了设置use_bet_model=True
之外,请确保两个数据集中的类平衡相同,或使用平衡精度指标来考虑不同的类平衡。
如果您已经完成了这两项操作,并且您仍然在测试集上看到比训练集更差的准确性指标,则表明过度拟合。我建议您利用CatBoost的过拟合检测器。最常见的第一种方法是将early_stopping_rounds
设置为像 10 这样的整数,一旦在该训练轮数后所选损失函数没有实现改进,它将停止训练(请参阅early_stopping_rounds文档)。