在XGBoost中使用带有参数的评估函数(f_beta)

时间:2016-12-09 12:39:43

标签: python xgboost

我正在研究一个分类问题,我有一个不平衡的数据集,我对高精度感兴趣。

因此,我想将XGBoost的目标函数更改为允许我更加重视精度的东西。 F_beta score似乎正在这样做,但我遇到了问题:

model_xgbm = XGBClassifier(objective=fbeta_score)
random_search = RandomizedSearchCV(model_xgbm, param_distributions=param_dist, n_iter=n_iter_search,
                               scoring='average_precision')

这样可行,但我没有提供测试版(我甚至不确定它是如何工作的,因为测试版是必修参数......)

model_xgbm = XGBClassifier(objective=fbeta_score(beta=0.5))
random_search = RandomizedSearchCV(model_xgbm, param_distributions=param_dist,
                                   n_iter=n_iter_search,
                                   scoring='average_precision')

这根本不起作用(“TypeError:fbeta_score()至少需要3个参数(给定1个)”)。但是,我不能在这里提供其他2个参数。

是否有解决方案没有复制或包装函数并粘贴为自定义目标?

编辑: 我找到了一个可能有用的函数:make_param,但不幸的是我似乎无法让它工作:

model_xgbm = XGBClassifier(objective=make_scorer(fbeta_score, beta=0.5))
random_search = RandomizedSearchCV(model_xgbm, param_distributions=param_dist,
                                   n_iter=n_iter_search,
                                   scoring='precision')

但这也不起作用:“TypeError:__ call __()至少需要4个参数(给定3个)” 请注意,我不想将它用于模型选择:我希望它是我的XGBoost估算器的目标函数!因此,上述链接底部的示例对我不起作用。

EDIT2:好的,所以事实上问题似乎是XGBoost分类器希望我提供一个返回渐变和粗麻布的函数作为目标...有没有人知道一个包装器会这样做吗?

1 个答案:

答案 0 :(得分:1)

查看这部分评论

eval_metric : str, callable, optional
        If a str, should be a built-in evaluation metric to use. See
        doc/parameter.md. If callable, a custom evaluation metric. The call
        signature is func(y_predicted, y_true) where y_true will be a
        DMatrix object such that you may need to call the get_label
        method. It must return a str, value pair where the str is a name
        for the evaluation and value is the value of the evaluation
        function. This objective is always minimized.

这实际上是错误的,因为你需要

func(y_true, y_predicted)

传递目标函数。

似乎如果你将f_beta_score包裹如下

def f_beta_wrapper(y_true, y_pred):
    beta = 0.5
    # note need to call .get_label() on y_true if using DMAtrix
    return fbeta_score(y_pred, y_true, beta)

并将其传递给。

它正确地流过,它到达你提到的问题fbeta_score返回float而不是它可以计算渐变的两个输出。更具体地说

  更新中的 /usr/local/lib/python2.7/site-packages/xgboost/core.pyc(self,dtrain,iteration,fobj)

     

807其他:

     

808 pred = self.predict(dtrain)

     

809 grad,hess = fobj(pred,dtrain)#错误在这里

     

810 self.boost(dtrain,grad,hess)

     

TypeError:'numpy.float64'对象不可迭代

这是有意义的,因为objective函数被最小化,因此我们需要类似于最小化参数的输出,即渐变。