1

我想通过 fit 方法传递 fit 的xgboost参数OneVsRestClassifier

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”

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

4

3 回答 3

1

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

使用当前框架,您无法通过fit_paramsfor OneVsRestClassifier。有关详细信息,请参阅此问题

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

更新:

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

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

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

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

于 2019-07-31T04:17:52.860 回答
1

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

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

于 2020-07-30T12:14:10.853 回答
1

我最近遇到了这个问题来动态传递 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 和 neg 比率(范围从 0.1% 到 10%)。下面是我创建的一个方法。假设我们有 X_train 作为训练特征,y_train 是每个类的二进制标签矩阵。我们可以解决并创建一个继承 fit 函数的新类,并为每个 y_train 数组传递一个 weight_array。OneVsRestClassifier 将 y_train 中的每个 y 一个一个传递,因此 weight_array 将单独计算。此解决方案仅适用于多标签的二进制分类([0,1])。我们要确保 neg 类的权重为 1,pos 类的权重为 (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.
      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 这样的整个类。

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

于 2020-01-10T19:30:20.273 回答