You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过GridSearchCV向自定义ColumnTransformer传递min_samples_leaf参数?

解决GridSearchCV传递参数给自定义列转换器的问题

错误原因

你当前的preprocessor是调用make_target_preprocessor后生成的ColumnTransformer实例,它本身没有min_samples_leaf参数——这个参数属于内部两个TargetEncoder组件,因此GridSearch找不到对应参数报错。

方案一:直接使用嵌套参数路径

利用sklearn的参数嵌套规则,通过组件的层级路径指定内部TargetEncoder的参数:

  • 第一个TargetEncoder的路径:preprocessor__targetencoder__min_samples_leaf(对应ColumnTransformer里第一个transformer的默认命名)
  • Pipeline内TargetEncoder的路径:preprocessor__pipeline-1__encoder__min_samples_leaf(对应第二个transformer的默认命名)

修改后的参数网格与代码:

pipe = Pipeline(steps=[
    ('preprocessor', make_target_preprocessor(min_samples_leaf=20, smoothing=10)),
    ('clf', LogisticRegression(max_iter=10000, random_state=11))
])

# 参数网格:同步调整两个TargetEncoder的min_samples_leaf
param_grid = [
    {
        'preprocessor__targetencoder__min_samples_leaf': [5, 10, 20],
        'preprocessor__pipeline-1__encoder__min_samples_leaf': [5, 10, 20]
    }
]

# 若要强制两个参数值一致,可生成同步组合
param_grid = [
    {
        'preprocessor__targetencoder__min_samples_leaf': [val],
        'preprocessor__pipeline-1__encoder__min_samples_leaf': [val]
    } for val in [5, 10, 20]
]

gs_lr = GridSearchCV(pipe, param_grid)

方案二:自定义可参数化的Transformer类

把预处理逻辑封装成继承自BaseEstimator和TransformerMixin的类,让min_samples_leaf和smoothing成为类的可调整参数,这样GridSearch可以直接传递参数:

from sklearn.base import BaseEstimator, TransformerMixin

class TargetPreprocessor(BaseEstimator, TransformerMixin):
    def __init__(self, min_samples_leaf=20, smoothing=10):
        self.min_samples_leaf = min_samples_leaf
        self.smoothing = smoothing
        self.transformer = None
    
    def fit(self, X, y=None):
        # 每次fit时根据当前参数构建ColumnTransformer
        self.transformer = make_column_transformer(
            (TargetEncoder(min_samples_leaf=self.min_samples_leaf, smoothing=self.smoothing),
             make_column_selector('^utm')),
            (Pipeline(steps=[
                ('imputer', DeviceBrandImputer()),
                ('encoder', TargetEncoder(min_samples_leaf=self.min_samples_leaf, smoothing=self.smoothing))
            ]),
             ['device_category', 'device_brand', 'device_browser'])
        )
        self.transformer.fit(X, y)
        return self
    
    def transform(self, X):
        return self.transformer.transform(X)

# 构建管道
pipe = Pipeline(steps=[
    ('preprocessor', TargetPreprocessor()),
    ('clf', LogisticRegression(max_iter=10000, random_state=11))
])

# 参数网格直接指向preprocessor的参数
param_grid = [{'preprocessor__min_samples_leaf': [5, 10, 20]}]
gs_lr = GridSearchCV(pipe, param_grid)

方案对比

  • 方案一:无需修改原有预处理函数,只需调整参数路径,但需要注意ColumnTransformer内组件的命名(可手动指定transformer的name参数避免默认命名变化)。
  • 方案二:代码结构更清晰,参数传递更直观,适合复杂预处理逻辑的参数调优。

内容的提问来源于stack exchange,提问作者Ars ML

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:27:52