python - 如何在 Brier 分数上优化提升树以进行分类?
问题描述
我有一个二进制分类任务并使用 xgboost 包来解决它。基本上,我只是使用增强树来做到这一点。但是我正在接受 Brier 分数的评估,所以我想我会优化 Brier 损失函数(定义为应用于逻辑分类之上的 brier 分数),这导致我定义了 Brier 损失的梯度和粗麻布,如下所示:
def brier(preds, dtrain):
labels = dtrain.get_label()
preds = 1.0 / (1.0 + np.exp(-preds))
grad = 2*(preds-labels)*preds*(1-preds)
hess = 2*(2*(labels+1)*preds-labels-3*preds*preds)*preds*(1-preds)
return grad, hess
def evalerror(preds, dtrain):
preds = 1.0 / (1.0 + np.exp(-preds))
labels = dtrain.get_label()
errors = (labels - preds)**2
return 'brier-error', float(np.sum(errors)) / len(labels)
param = {'eta':0.01,
'max_depth': 6, # the maximum depth of each tree
#'objective': 'binary:logistic',
'booster' : 'gbtree',
'eval_metric':['rmse', 'auc']}
bst = xgb.train(param,dtrain, num_boost_round=999,early_stopping_rounds=10,obj=brier, feval=evalerror,evals=[(dtrain,'train'),(dtest,'test')])
唯一的问题是,通过这样做,我在测试集上的预测得到了负值,这表明 xgboost 模型的输出不是预期的逻辑概率。有谁知道我在这里缺少什么,或者是否有更好的方法来优化 brier 分数?
任何帮助将非常感激!!
谢谢,
解决方案
我遇到了同样的问题并进行了一些调查。我认为 OP 的计算是正确的,这里的问题不是使用对角近似而不是 @Damodar8 建议的精确粗麻布,因为它指的是多类分类问题。
正如这里指出的:
注意:当你做自定义损失函数时,默认的预测值为margin。这可能会使内置评估指标无法正常运行例如,我们正在做逻辑损失,预测是逻辑转换之前的分数内置评估错误假设输入是在逻辑转换之后 使用自定义时请记住这一点,也许您需要编写自定义评价函数
尽管评论本身很难解开,但粗体字解释了 OP 的问题。解决方案是仅对结果使用逻辑转换bst.predict
。完整示例如下:
import numpy as np
import xgboost as xgb
dtrain = xgb.DMatrix('/home/kuba/Desktop/agaricus.txt.train')
dtest = xgb.DMatrix('/home/kuba/Desktop/agaricus.txt.test')
def brier(preds, dtrain):
labels = dtrain.get_label()
preds = 1.0 / (1.0 + np.exp(-preds))
grad = 2*(preds-labels)*preds*(1-preds)
hess = 2*(2*(labels+1)*preds-labels-3*preds*preds)*preds*(1-preds)
return grad, hess
def evalerror(preds, dtrain):
preds = 1.0 / (1.0 + np.exp(-preds))
labels = dtrain.get_label()
errors = (labels - preds)**2
return 'brier-error', float(np.sum(errors)) / len(labels)
param = {'max_depth': 2, 'eta': 1, 'silent': 1}
watchlist = [(dtest, 'eval'), (dtrain, 'train')]
num_round = 2
bst = xgb.train(param, dtrain, num_round, watchlist, obj=brier, feval=evalerror)
pred = bst.predict(dtest)
pred.min(), pred.max()
# (-5.809054, 2.2280416)
prob = 1 / (1 + np.exp(-pred))
prob.min(), prob.max()
# (0.0029912924, 0.9027395)
推荐阅读
- spring - 未对 @Transactional 注解执行回滚
- python-3.x - 是否可以在不定义顺序或关键字之间的单词数的情况下使用基于空间规则的匹配?
- node.js - 断言传递给存根函数的函数是正确的函数
- javascript - 如何在 Tempus Dominus datetimepicker 中修复“未捕获的类型错误:无法读取未定义的属性‘格式’”?
- php - 在外键约束错误中需要的学说
- amazon-web-services - 如何在将数据从 S3 存储桶(使用 kms 密钥)复制到 Redshift 时删除访问被拒绝错误。(S3 存储桶在跨账户中)?
- android - 编辑音乐标题在 Android Q 中不起作用?
- html - 如何编辑此代码段以在同一行显示按钮?
- c# - 在 ASPNET Core 中注册具有两个不同生命周期范围的依赖项
- terraform - 如果未在 Terraform 中创建资源,如何使用资源变量