如何为管道中的不同“步骤”找到最佳参数?

Posted

技术标签:

【中文标题】如何为管道中的不同“步骤”找到最佳参数?【英文标题】:How to find the best parameters for different "steps" in a pipeline? 【发布时间】:2021-10-11 13:23:52 【问题描述】:

我有以下结合了预处理、特征选择和估计器的管道:

## Selecting categorical and numeric features
numerical_ix = X.select_dtypes(include=np.number).columns
categorical_ix = X.select_dtypes(exclude=np.number).columns

## Create preprocessing pipelines for each datatype 
numerical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())])

categorical_transformer = Pipeline(steps=[
    ('encoder', OrdinalEncoder()),
    ('scaler', StandardScaler())])

## Putting the preprocessing steps together
preprocessor = ColumnTransformer([
        ('numerical', numerical_transformer, numerical_ix),
        ('categorical', categorical_transformer, categorical_ix)],
         remainder='passthrough')

## Create example pipeline with kNN
example_pipe = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('selector', SelectKBest(k=len(X.columns))), # keep the same amount of columns for now
    ('classifier', KNeighborsClassifier())
])

cross_val_score(example_pipe, X, y, cv=5, scoring='accuracy').mean()

我编写了以下代码,为SelectKBest“尝试”不同的ks 并绘制它。

但我如何同时在 kNN 分类器中寻找 k 的最佳值?我不一定要绘制它,只是找到最优值。我的猜测是GridSearchCV,但我不知道如何将其应用于管道中的不同步骤。

k_range = list(range(1, len(X.columns))) # 1 until 18
k_scores = []

for k in k_range:
  example_pipe = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('selector', SelectKBest(k=k)), # keep the same amount of columns for now
    ('classifier', KNeighborsClassifier())])
  score = cross_val_score(example_pipe, X, y, cv=5, scoring='accuracy').mean()
  k_scores.append(score)

plt.plot(k_range, k_scores)
plt.xlabel('Value of k in SelectKBEST')
plt.xticks(k_range, rotation=20) 
plt.ylabel('Cross-Validated Accuracy')

对于那些感兴趣的人,输出是:

【问题讨论】:

【参考方案1】:

您正在寻找KNeighborsClassifier 的最佳n_neighbors 值。

您对此使用GridSearchCV 的猜测是正确的。如果你想了解它与管道的结合使用,请查看Pipeline的文档:

流水线的目的是在设置不同参数的同时将几个可以交叉验证的步骤组合在一起。为此,它可以使用它们的名称和由“__”分隔的参数名称来设置各个步骤的参数

在你的情况下:

example_pipe = Pipeline(steps=[
    ('preprocessor', preprocessor),
    ('selector', SelectKBest()),
    ('classifier', KNeighborsClassifier())
])

param_grid = 
    "selector__k": [5, 10, 15],
    "classifier__n_neighbors": [3, 5, 10]


gs = GridSearchCV(example_pipe, param_grid=param_grid)
gs.fit(X, y)

然后用best_params_检索最佳参数:

best_k = gs.best_params_['selector__k']
best_n_neighbors = gs.best_params_['classifier__n_neighbors']

【讨论】:

以上是关于如何为管道中的不同“步骤”找到最佳参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 k-NN 找到 k 的最佳值?

如何为 SVM 线性核类型选择最佳参数

python中的多存储库管道

如何为不同的请求方法创建具有不同参数编码的 AFHttpClient?

如何为管道中的异常值删除实现 Python 自定义类?

如何为Laravel中的每个会话设置不同的到期时间?