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

How to pass XGBoost fit parameters when using OneVsRestClassifier?

我想通过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)

Error: fit() got an unexpected keyword argument 'estimator__eval_metric'

请问如何使用 OneVsRestClassifier 拟合方法传递 XGBoost 拟合参数?

XGBoost 默认处理多 class class 化。请参阅 this 示例以获取更多说明。

在当前框架下,您无法将 fit_params 传递给 OneVsRestClassifier。有关更多详细信息,请参阅此 issue

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

更新:

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

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

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

介绍了减少过度拟合的其他最佳选择here

我最近 运行 这个问题要动态传递 pos_scale_weight,下面是我如何解决这个问题。当前没有可用于 XGBClassifier class 的自动 pos_scale_weight。我们真的想将 sklearn OneVsRestClassifier 与 xgboost 一起用于多标签或多 class class 化问题。

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     |

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

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.
      
      """  
      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 对每个实例都有权重而不是整个 class 像 pos_scale_weight.

并且此方法将整个 class 的权重(在每个标签内)同等对待。

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

weight_array = y * weight + 1
(否则你给负面的权重为 0 class...)