使用sklearn的GridSearchCV与管道,仅进行一次预处理

我正在使用scikit-learn来调整模型的超参数。我使用管道将预处理与估计器连接起来。我问题的简化版本如下所示:

import numpy as npfrom sklearn.model_selection import GridSearchCVfrom sklearn.pipeline import make_pipelinefrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressiongrid = GridSearchCV(make_pipeline(StandardScaler(), LogisticRegression()),                    param_grid={'logisticregression__C': [0.1, 10.]},                    cv=2,                    refit=False)_ = grid.fit(X=np.random.rand(10, 3),             y=np.random.randint(2, size=(10,)))

在我的情况下,预处理(在示例中是StandardScaler())非常耗时,而且我没有调整它的任何参数。

因此,当我执行这个示例时,StandardScaler会被执行12次。2次fit/predict * 2次cv * 3个参数。但每次StandardScaler为参数C的不同值执行时,它返回的输出都是相同的,因此,如果能计算一次,然后只运行管道的估计器部分,将会更加高效。

我可以手动将管道拆分为预处理部分(不调整超参数)和估计器部分。但要对数据应用预处理,我应该只提供训练集。因此,我将不得不手动实现分割,并且完全不使用GridSearchCV。

在使用GridSearchCV时,有没有简单/标准的方法可以避免重复预处理?


回答:

更新:理想情况下,以下答案不应使用,因为如评论中讨论的,它会导致数据泄露。在这个答案中,GridSearchCV将在已由StandardScaler预处理的数据上调整超参数,这是错误的。在大多数情况下这不会有太大影响,但对缩放过于敏感的算法会给出错误的结果。


本质上,GridSearchCV也是一个估计器,实现了fit()和predict()方法,被管道使用。

所以不是这样做:

grid = GridSearchCV(make_pipeline(StandardScaler(), LogisticRegression()),                    param_grid={'logisticregression__C': [0.1, 10.]},                    cv=2,                    refit=False)

而是这样做:

clf = make_pipeline(StandardScaler(),                     GridSearchCV(LogisticRegression(),                                 param_grid={'logisticregression__C': [0.1, 10.]},                                 cv=2,                                 refit=True))clf.fit()clf.predict()

这样做会只调用一次StandardScaler(),在一次clf.fit()调用中,而不是像你描述的多次调用。

编辑:

当GridSearchCV在管道内使用时,将refit改为True。如文档中提到的

refit : 布尔值,默认值=True 使用整个数据集重新拟合最佳估计器。如果为“False”,在拟合后无法使用此GridSearchCV实例进行预测。

如果refit=False,clf.fit()将无效,因为管道内的GridSearchCV对象会在fit()后被重新初始化。当refit=True时,GridSearchCV将使用在fit()中传入的整个数据重新拟合最佳得分的参数组合。

所以如果你只是想查看网格搜索的得分,那么refit=False是合适的。如果你想调用clf.predict()方法,必须使用refit=True,否则会抛出未拟合错误。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注