使用OneVsRestClassifier时如何传递XGBoost拟合参数?



我想通过OneVsRestClassifier的拟合方法传递xgboost的拟合参数。

clf = OneVsRestClassifier( XGBClassifier(objective='binary:logistic', seed=0))
# Want to pass `eval_set` and 'eval_metric' to xgboost model.
clf.fit(X_train, y_train, estimator__eval_metric='aucpr', estimator__eval_set= eval_set_xgboost)

错误:fit() 得到一个意外的关键字参数"estimator__eval_metric">

你能帮我如何使用OneVsRestClassifier拟合方法传递XGBoost拟合参数吗?

默认情况下XGBoost处理多类分类。有关更多说明,请参阅此示例。

使用当前框架,您无法传递fit_paramsforOneVsRestClassifier。有关更多详细信息,请参阅此问题。

也许,如果您能与OneVsRestClassifier分享您的包装意图,我们可以适当地指导您。

更新:

我不认为用一个 Vs rest 分类器包装会减少过度拟合。

使用简单的 XGBoost,但微调超参数。

  • 第一选择是降低学习率,同时增加训练的迭代次数。

此处简要介绍了减少过度拟合的其他最佳选择

Chandler Sekai的回答很有帮助。但是,需要更改一行:

weight_array = y * weight + 1
(否则你给负类0权重...

我最近遇到了这个问题以动态传递pos_scale_weight,以下是我如何解决该解决方案。目前没有可用于 XGBClassifier 类的自动pos_scale_weight。我们真的想将sklearn OneVsRestClassifier与xgboost一起使用来解决多标签或多类分类问题。

使用OneVsRestClassifier的常用方法如下:

clf = OneVsRestClassifier(XGBClassifier(booster='gbtree', objective='binary:logistic'))
clf.fit(X=X_train, y = y_train)

OneVsRestClassifier的作用是:当你调用clf.fit时,它实际上调用XGBClassifier的fit方法来拟合X_train,并从y_train中调用每个目标来拟合训练数据。在下面的示例中,clf.fit 方法将:XGBClassifier.fit(X_train, target1) -> XGBClassifier.fit(X_train, target2) -> XGBClassifier.fit(X_train, target3) -> 集成所有三个模型。如果将pos_scale_weight设置为某个数字,则每个拟合将使用相同的比例。如果所有三个目标的正比率差异很大。它将不符合阳性率远低于其他目标的目标。

y_train.head()
| target1| target2 |target3|
|--------|---------|-------|
| 0      | 1       | 0     |
| 1      | 1       | 0     |

在我的挑战中,我预测的每个标签都有完全不同的pos和负比(范围从0.1%到10%)。下面是我创建的方法。假设我们有X_train作为训练特征,y_train是每个类的二进制标签矩阵。我们可以变通并创建一个继承 fit 函数的新类,并为每个y_train数组传递一个weight_array。OneVsRestClassifier将逐个传递y_train中的每个y,因此weight_array将单独计算。此解决方案仅适用于多标签的二元分类([0,1])。我们要确保负类的权重为 1,pos 类的权重为 (neg 的 num)/(pos 的 num

)。
class XGBClassifierNew(XGBClassifier):
"""
the inherited class with same method name will override.
if you start an XGBClassifierNew instance the fit method you called by default will be XGBClassifierNew.fit(). Check the link below for reference.
https://stackoverflow.com/questions/12764995/python-overriding-an-inherited-class-method
"""  
def fit(self, X, y, **kwargs):
pos_ratio = y.sum()/len(y)
weight = len(y)/y.sum() - 1
weight_array = y * (weight-1) + 1
return super().fit(X=X, y=y, sample_weight = weight_array, **kwargs)
clf = OneVsRestClassifier(XGBClassifierNew())
clf.fit(X=X_train, y=y_train)

weight_array 是一个数组的原因是sample_weight为每个实例而不是像 pos_scale_weight 那样的整个类获取权重。

这种方法对整个类的权重(在每个标签内)一视同仁。

最新更新