SKLEARN // 将 GridsearchCV 与列变换和管道相结合

Posted

技术标签:

【中文标题】SKLEARN // 将 GridsearchCV 与列变换和管道相结合【英文标题】:SKLEARN // Combine GridsearchCV with column transform and pipeline 【发布时间】:2020-10-01 12:39:05 【问题描述】:

我正在努力完成一个机器学习项目,我正在尝试将其结合起来:

sklearn 列变换,可将不同的变换器应用于我的数值和分类特征 应用我的不同转换器和估算器的管道 GridSearchCV 搜索最佳参数。

只要我在管道中手动填写不同转换器的参数,代码就可以完美运行。 但是,一旦我尝试传递不同值的列表以在我的网格搜索参数中进行比较,我就会收到各种无效参数错误消息。

这是我的代码:

首先我将我的特征分为数值型和分类型

from sklearn.compose import make_column_selector
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.impute import KNNImputer
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder


numerical_features=make_column_selector(dtype_include=np.number)
cat_features=make_column_selector(dtype_exclude=np.number)

然后我为数值和分类特征创建了 2 个不同的预处理管道:

numerical_pipeline= make_pipeline(KNNImputer())
cat_pipeline=make_pipeline(SimpleImputer(strategy='most_frequent'),OneHotEncoder(handle_unknown='ignore'))

我将两者合并到另一个管道中,设置我的参数,然后运行我的GridSearchCV 代码

model=make_pipeline(preprocessor, LinearRegression() )

params=
    'columntransformer__numerical_pipeline__knnimputer__n_neighbors':[1,2,3,4,5,6,7]


grid=GridSearchCV(model, param_grid=params,scoring = 'r2',cv=10)
cv = KFold(n_splits=5)
all_accuracies = cross_val_score(grid, X, y, cv=cv,scoring='r2')

我尝试了不同的方法来声明参数,但从未找到合适的方法。我总是收到“无效参数”错误消息。

您能帮我了解一下出了什么问题吗?

非常感谢您的支持,请保重!

【问题讨论】:

您省略了preprocessor 的定义。试试grid.get_params() 【参考方案1】:

我假设您可能已将preprocessor 定义为以下内容,

preprocessor = Pipeline([('numerical_pipeline',numerical_pipeline),
                        ('cat_pipeline', cat_pipeline)])

然后你需要改变你的参数名称如下:

pipeline__numerical_pipeline__knnimputer__n_neighbors

但是,代码还有其他几个问题:

    您不必在执行GridSearchCV 后调用cross_val_score。 GridSearchCV 本身的输出将具有每个超参数组合的交叉验证结果。

    KNNImputer 在您的数据包含字符串数据时不起作用。您需要在num_pipeline 之前申请cat_pipeline

完整示例:

from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import make_column_transformer
from sklearn.compose import make_column_selector
import pandas as pd  # doctest: +SKIP
X = pd.DataFrame('city': ['London', 'London', 'Paris', np.nan],
                  'rating': [5, 3, 4, 5])  # doctest: +SKIP

y = [1,0,1,1]

from sklearn.compose import make_column_selector
from sklearn.pipeline import make_pipeline, Pipeline
from sklearn.model_selection import GridSearchCV
from sklearn.impute import KNNImputer
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score, KFold
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder


numerical_features=make_column_selector(dtype_include=np.number)
cat_features=make_column_selector(dtype_exclude=np.number)

numerical_pipeline= make_pipeline(KNNImputer())
cat_pipeline=make_pipeline(SimpleImputer(strategy='most_frequent'),
                            OneHotEncoder(handle_unknown='ignore', sparse=False))
preprocessor = Pipeline([('cat_pipeline', cat_pipeline),
                        ('numerical_pipeline',numerical_pipeline)])
model=make_pipeline(preprocessor, LinearRegression() )

params=
    'pipeline__numerical_pipeline__knnimputer__n_neighbors':[1,2]



grid=GridSearchCV(model, param_grid=params,scoring = 'r2',cv=2)

grid.fit(X, y)

【讨论】:

感谢您的及时和非常详细的反馈。这真的很有帮助,现在运行良好。为了创建预处理器管道,我使用了 make_pipeline 而不是管道,这似乎是瓶颈。还要感谢有关 cat_pipeline 和 numeric_pipeline 的提示。我认为由于 trnasform 列允许不同的预处理,它们的顺序无关紧要。再次非常感谢,祝您有美好的一天! ColumnTransformer 转换器的顺序无关紧要。这个答案不包括 ColumnTransformer,而是另一个管道。 没错。这里使用 columntransformer 没有用,因为我们必须在 knn imputer 之前应用 ohe @Venkatachalam:还有一个我不明白的元素。在我的数值特征中,我想添加额外的转换器,如下所示: numeric_pipeline= make_pipeline(KNNImputer(),preprocessing.StandardScaler(),PolynomialFeatures()) 但我没有找到在 gridsearchCV 中测试多项式特征的正确方法参数。按照您的指导,我添加了: 'pipeline__numerical_pipeline__polynomialfeatures__degree':[2,3,4] 但似乎这不起作用。在这种情况下你能帮我吗?非常感谢 当然,你能把这个问题作为一个单独的问题来询问更多细节吗?

以上是关于SKLEARN // 将 GridsearchCV 与列变换和管道相结合的主要内容,如果未能解决你的问题,请参考以下文章

将 sklearn 的 BaggingClassifier 与 GridSearchCV 一起使用时出现 ZeroDivisionError

将 Sklearn Pipiline 分支到 GridSearchCV 时出现问题

如何将两个估计器对象传递给 sklearn 的 GridSearchCV,以便它们在每个步骤中具有相同的参数?

如何使用 sklearn 中的 GridSearchCV 设置自己的评分以进行回归?

将 Sklearn GridSearchCV 与 Pipeline 一起使用时如何传递权重

GridSearchCV 的 sklearn 中的自定义“k 精度”评分对象