如何使用 XGboost 针对不同的“eval_metric”优化 sklearn 管道?

Posted

技术标签:

【中文标题】如何使用 XGboost 针对不同的“eval_metric”优化 sklearn 管道?【英文标题】:How to optimize a sklearn pipeline, using XGboost, for a different `eval_metric`? 【发布时间】:2017-08-05 05:52:04 【问题描述】:

我正在尝试使用XGBoost,并将eval_metric 优化为auc(如here 所述)。

直接使用分类器时效果很好,但当我尝试将其用作pipeline 时会失败。

.fit 参数传递给sklearn 管道的正确方法是什么?

例子:

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from xgboost import XGBClassifier
import xgboost
import sklearn

print('sklearn version: %s' % sklearn.__version__)
print('xgboost version: %s' % xgboost.__version__)

X, y = load_iris(return_X_y=True)

# Without using the pipeline: 
xgb = XGBClassifier()
xgb.fit(X, y, eval_metric='auc')  # works fine

# Making a pipeline with this classifier and a scaler:
pipe = Pipeline([('scaler', StandardScaler()), ('classifier', XGBClassifier())])

# using the pipeline, but not optimizing for 'auc': 
pipe.fit(X, y)  # works fine

# however this does not work (even after correcting the underscores): 
pipe.fit(X, y, classifier__eval_metric='auc')  # fails

错误:TypeError: before_fit() got an unexpected keyword argument 'classifier__eval_metric'

关于 xgboost 的版本:xgboost.__version__ 显示 0.6pip3 freeze | grep xgboost 显示 xgboost==0.6a2

【问题讨论】:

你试过'roc_auc'吗? 它适用于 sklearn 版本:0.18 xgboost 版本:0.6 【参考方案1】:

错误是因为您在管道中使用时在估算器名称及其参数之间使用了一个下划线。应该是两个下划线。

从documentation of Pipeline.fit() 中,我们看到提供合适参数的正确方法:

传递给每个步骤的fit方法的参数,其中每个参数名称都带有前缀,以便步骤s的参数p具有键s__p。

所以在你的情况下,正确的用法是:

pipe.fit(X_train, y_train, classifier__eval_metric='auc')

(注意名称和参数之间有两个下划线)

【讨论】:

不幸的是,这也不起作用,将其添加到原始问题的测试选项中。我认为如果它是分类器的参数(例如nr_estimators)会起作用,但它是该特定分类器的 fit 方法的参数。 我正在使用来自 sklearn 的虹膜数据,它工作正常(没有抛出任何错误)。请更新您的 scikit 和/或 xgboost 版本,然后重试 有趣,能告诉我你使用的版本吗?我正在使用 xgboost 版本 '0.6' 和 sklearn 版本 '0.18.1' 肯定发生了一些奇怪的事情。 xgboost.__version__ 由于某种原因显示与 pip freeze 不同的东西。我更改了示例以使其可与 iris 数据集一起复制,请问您是否可以在您的数据集上运行它? (非常感谢,即使感谢人们不是这样的政策) 我已经编辑了您的复制和粘贴代码。我还尝试了 Python 2.7.6 和 Python 3.4.3,它工作正常。【参考方案2】:

当目标是优化时,我建议使用 sklearn 包装器和 GridSearchCV

from xgboost.sklearn import XGBClassifier
from sklearn.grid_search import GridSearchCV

看起来像

pipe = Pipeline([('scaler', StandardScaler()), ('classifier', XGBClassifier())])

score = 'roc_auc'
pipe.fit(X, y) 

param = 
 'classifier_max_depth':[1,2,3,4,5,6,7,8,9,10] # just as example


gsearch = GridSearchCV(estimator =pipe, param_grid =param , scoring= score)

你也可以使用交叉验证技术

gsearch.fit(X, y)

你会得到最好的参数和最好的分数

gsearch.best_params_, gsearch.best_score_

【讨论】:

以上是关于如何使用 XGboost 针对不同的“eval_metric”优化 sklearn 管道?的主要内容,如果未能解决你的问题,请参考以下文章

“xgboost”官方包与 R 中“caret”包中的 xgboost 的不同结果

如何知道在 XGBoost 中创建的树的数量

XgBoost的总结

`object` 和 `newdata` 中存储的特征名称不同!使用 LIME 包解释 R 中的 xgboost 模型时

为啥 xgboost.cv 和 sklearn.cross_val_score 给出不同的结果?

使用来自 H2O 的超参数在 Sklearn 中重新构建 XGBoost 在 Python 中提供了不同的性能