使用网格搜索获取最佳模型的“并行”管道

在sklearn中,可以定义一个串行管道来获取管道中所有连续部分的最佳超参数组合。串行管道可以按以下方式实现:

from sklearn.svm import SVCfrom sklearn import decomposition, datasetsfrom sklearn.pipeline import Pipelinefrom sklearn.model_selection import GridSearchCVdigits = datasets.load_digits()X_train = digits.datay_train = digits.target#使用主成分分析来降低维度#并改善泛化能力pca = decomposition.PCA()#使用线性SVCsvm = SVC()#将PCA和SVC组合成一个管道pipe = Pipeline(steps=[('pca', pca), ('svm', svm)])#检查SVC的训练时间n_components = [20, 40, 64]params_grid = {'svm__C': [1, 10, 100, 1000],'svm__kernel': ['linear', 'rbf'],'svm__gamma': [0.001, 0.0001],'pca__n_components': n_components,}

但是,如果我想为管道的每个步骤尝试不同的算法呢?例如,我如何对以下内容进行网格搜索?

主成分分析 OR 奇异值分解 AND 支持向量机 OR 随机森林

这将需要某种第二级或“元网格搜索”,因为模型的类型将是超参数之一。在sklearn中这是可能的吗?


回答:

Pipeline在其steps(估算器列表)中支持None,通过这种方式可以关闭管道的某些部分。

您可以通过向传递给GridSearchCV的参数中设置named_stepsNone参数来不使用该估算器。

假设您想使用PCATruncatedSVD

pca = decomposition.PCA()svd = decomposition.TruncatedSVD()svm = SVC()n_components = [20, 40, 64]

在管道中添加svd

pipe = Pipeline(steps=[('pca', pca), ('svd', svd), ('svm', svm)])# 更改params_grid -> 改为列表中的字典**# 在第一个元素中,传递`svd = None`,在第二个元素中传递`pca = None`params_grid = [{'svm__C': [1, 10, 100, 1000],'svm__kernel': ['linear', 'rbf'],'svm__gamma': [0.001, 0.0001],'pca__n_components': n_components,'svd':[None]},{'svm__C': [1, 10, 100, 1000],'svm__kernel': ['linear', 'rbf'],'svm__gamma': [0.001, 0.0001],'pca':[None],'svd__n_components': n_components,'svd__algorithm':['randomized']}]

现在只需将管道对象传递给gridsearchCV

grd = GridSearchCV(pipe, param_grid = params_grid)

调用grd.fit()将会在params_grid列表的两个元素上搜索参数,每次使用其中一个的所有值。

如果参数名称相同时的简化

如果您在“OR”中的两个估算器具有相同的参数名称,如本例中的PCATruncatedSVD都有n_components(或者您只想搜索这个参数),可以简化为:

#在这里我已将名称更改为`preprocessor`pipe = Pipeline(steps=[('preprocessor', pca), ('svm', svm)])#现在将两个估算器都分配给`preprocessor`,如下所示:params_grid = {'svm__C': [1, 10, 100, 1000],'svm__kernel': ['linear', 'rbf'],'svm__gamma': [0.001, 0.0001],'preprocessor':[pca, svd],'preprocessor__n_components': n_components,}

此方案的泛化

我们可以创建一个函数来自动填充我们的param_grid,以便将其提供给GridSearchCV使用适当的值:

def make_param_grids(steps, param_grids):    final_params=[]    # Itertools.product将执行排列,使得     # (pca OR svd) AND (svm OR rf) 将变为 ->    # (pca, svm) , (pca, rf) , (svd, svm) , (svd, rf)    for estimator_names in itertools.product(*steps.values()):        current_grid = {}        # 步骤名称和估算器名称应对应        # 即preprocessor必须来自pca和select。        for step_name, estimator_name in zip(steps.keys(), estimator_names):            for param, value in param_grids.get(estimator_name).iteritems():                if param == 'object':                    # 在管道中设置实际的估算器                    current_grid[step_name]=[value]                else:                    # 设置上述估算器对应的参数                    current_grid[step_name+'__'+param]=value        #将此字典追加到最终参数中                    final_params.append(current_grid)return final_params

并在任意数量的转换器和估算器上使用此函数

# 将所有您想要“OR”的估算器添加到单个键中# 在`pca`和`select`之间使用OR,# 在`svm`和`rf`之间使用OR# 不同的键将被评估为管道中的串行估算器pipeline_steps = {'preprocessor':['pca', 'select'],                  'classifier':['svm', 'rf']}# 在此字典中填写要搜索的参数all_param_grids = {'svm':{'object':SVC(),                           'C':[0.1,0.2]                         },                    'rf':{'object':RandomForestClassifier(),                         'n_estimators':[10,20]                        },                   'pca':{'object':PCA(),                          'n_components':[10,20]                         },                   'select':{'object':SelectKBest(),                             'k':[5,10]                            }                  }  # 在上述声明的变量上调用该方法param_grids_list = make_param_grids(pipeline_steps, all_param_grids)

现在使用上面pipeline_steps中使用的名称初始化一个管道对象

# 这里使用的PCA()和SVC()只是为了初始化管道,# 实际的估算器将从我们的`param_grids_list`中使用pipe = Pipeline(steps=[('preprocessor',PCA()), ('classifier', SVC())])  

现在,最终设置我们的gridSearchCV对象并拟合数据

grd = GridSearchCV(pipe, param_grid = param_grids_list)grd.fit(X, y)

Related Posts

L1-L2正则化的不同系数

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

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

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

f1_score metric in lightgbm

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

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

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

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

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

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

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

发表回复

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