具有多个转换和估计器的 Sklearn 管道
Sklearn Pipeline with multiple transforms and estimators
我正在尝试使用 Pipeline 构建 GridSearchCV,我想同时测试转换器和估算器。
有没有更简洁的方法呢?
pipeline = Pipeline([
('imputer', SimpleImputer()),
('scaler', StandardScaler()),
('pca', PCA()),
('clf', KNeighborsClassifier())
])
parameters = [{
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
'pca__n_components': (10, 20),
'clf': (LogisticRegression(),),
'clf__C': (1,10)
}, {
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
'pca__n_components': (10, 20),
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}, {
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
'pca__n_components': (10, 20),
'clf': (LogisticRegression(),),
'clf__C': (1,10)
}, {
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
'pca__n_components': (10, 20),
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}]
grid_search = GridSearchCV(estimator=pipeline, param_grid=parameters)
除了有 4 个参数块,我想声明我想使用相应参数和 2 个分类器测试的 2 个插补方法。并且不给 pca__n_components 贴花 4 次。
当您获得相互依赖的超参数时,参数网格方法会变得很麻烦。有几种方法可以获得您需要的东西。
嵌套网格搜索
GridSearchCV(
estimator=GridSearchCV(estimator=pipeline, param_grid=imputer_grid),
param_grid=estimator_grid,
)
对于每个估计器候选者,这对输入者候选者运行网格搜索;最好的 imputer 用于估计器,然后比较 estimators-with-best-imputers。
这里的主要缺点是内部搜索被克隆到每个估计器候选者,因此您无法访问 non-winning 估计器的输入器的 cv_results_
。
python 生成(部分)网格
ParameterGrid
,由 GridSearchCV
内部使用,主要是 itertools.product
的包装。所以我们可以使用 itertools
自己来创建(块)网格。例如。我们可以创建您编写的列表,但重复代码较少:
import itertools
imputers = [{
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
},
{
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
}]
models = [{
'clf': (LogisticRegression(),),
'clf__C': (1,10),
},
{
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}]
pcas = [{'pca__n_components': (10, 20),}]
parameters = [
{**imp, **pca, **model} # in py3.9 the slicker notation imp | pca | model works
for imp, pca, model in itertools.product(imputers, pca, models)
] # this should give the same as your hard-coded list-of-dicts
我正在尝试使用 Pipeline 构建 GridSearchCV,我想同时测试转换器和估算器。 有没有更简洁的方法呢?
pipeline = Pipeline([
('imputer', SimpleImputer()),
('scaler', StandardScaler()),
('pca', PCA()),
('clf', KNeighborsClassifier())
])
parameters = [{
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
'pca__n_components': (10, 20),
'clf': (LogisticRegression(),),
'clf__C': (1,10)
}, {
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
'pca__n_components': (10, 20),
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}, {
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
'pca__n_components': (10, 20),
'clf': (LogisticRegression(),),
'clf__C': (1,10)
}, {
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
'pca__n_components': (10, 20),
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}]
grid_search = GridSearchCV(estimator=pipeline, param_grid=parameters)
除了有 4 个参数块,我想声明我想使用相应参数和 2 个分类器测试的 2 个插补方法。并且不给 pca__n_components 贴花 4 次。
当您获得相互依赖的超参数时,参数网格方法会变得很麻烦。有几种方法可以获得您需要的东西。
嵌套网格搜索
GridSearchCV(
estimator=GridSearchCV(estimator=pipeline, param_grid=imputer_grid),
param_grid=estimator_grid,
)
对于每个估计器候选者,这对输入者候选者运行网格搜索;最好的 imputer 用于估计器,然后比较 estimators-with-best-imputers。
这里的主要缺点是内部搜索被克隆到每个估计器候选者,因此您无法访问 non-winning 估计器的输入器的 cv_results_
。
python 生成(部分)网格
ParameterGrid
,由 GridSearchCV
内部使用,主要是 itertools.product
的包装。所以我们可以使用 itertools
自己来创建(块)网格。例如。我们可以创建您编写的列表,但重复代码较少:
import itertools
imputers = [{
'imputer': (SimpleImputer(), ),
'imputer__strategy': ('median', 'mean'),
},
{
'imputer': (KNNImputer(), ),
'imputer__n_neighbors': (5, 10),
}]
models = [{
'clf': (LogisticRegression(),),
'clf__C': (1,10),
},
{
'clf': (KNeighborsClassifier(),),
'clf__n_neighbors': (10, 25),
}]
pcas = [{'pca__n_components': (10, 20),}]
parameters = [
{**imp, **pca, **model} # in py3.9 the slicker notation imp | pca | model works
for imp, pca, model in itertools.product(imputers, pca, models)
] # this should give the same as your hard-coded list-of-dicts