【问题标题】:How to use GridSearchCV for comparing multiple models along with pipeline and hyper-parameter tuning in python如何使用 GridSearchCV 比较多个模型以及 python 中的管道和超参数调整
【发布时间】:2020-08-24 03:13:23
【问题描述】:

我正在使用两个估计器,随机森林和 SVM

random_forest_pipeline=Pipeline([   
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('random_forest',RandomForestClassifier())
])
svm_pipeline=Pipeline([
    ('vectorizer',CountVectorizer(stop_words='english')),
    ('svm',LinearSVC())
])

我想首先对数据进行矢量化,然后使用估计器,我正在通过这个在线 tutorial 。然后我使用超参数如下

parameters=[
    {
        'vectorizer__max_features':[500,1000,1500],
        'random_forest__min_samples_split':[50,100,250,500]
    },
    {
        'vectorizer__max_features':[500,1000,1500],
        'svm__C':[1,3,5]
    }
]

并传递给GridSearchCV

pipelines=[random_forest_pipeline,svm_pipeline]
grid_search=GridSearchCV(pipelines,param_grid=parameters,cv=3,n_jobs=-1)
grid_search.fit(x_train,y_train)

但是,当我运行代码时,我得到一个错误

TypeError: estimator 应该是一个实现 'fit' 方法的估计器

不知道为什么会出现这个错误

【问题讨论】:

    标签: python python-3.x scikit-learn pipeline gridsearchcv


    【解决方案1】:

    问题在于pipelines=[random_forest_pipeline,svm_pipeline] 是一个没有fit 方法的列表。

    即使您可以使其以这种方式工作,在某些时候'random_forest__min_samples_split':[50,100,250,500] 也会在svm_pipeline 中传递,这会引发错误。

    ValueError:估计器管道的参数 svm 无效

    您不能以这种方式混合 2 个管道,因为在某些时候您请求使用 random_forest__min_samples_split 的值评估 svm_pipeline,这是无效的。


    解决方案:Fit a GridSearch object for the Random forest model and another GridSearch object for the SVC model

    pipelines=[random_forest_pipeline,svm_pipeline]
    
    grid_search_1=GridSearchCV(pipelines[0],param_grid=parameters[0],cv=3,n_jobs=-1)
    grid_search_1.fit(X,y)
    
    grid_search_2=GridSearchCV(pipelines[1],param_grid=parameters[1],cv=3,n_jobs=-1)
    grid_search_2.fit(X,y)
    

    完整代码:

    random_forest_pipeline=Pipeline([   
        ('vectorizer',CountVectorizer(stop_words='english')),
        ('random_forest',RandomForestClassifier())
    ])
    svm_pipeline=Pipeline([
        ('vectorizer',CountVectorizer(stop_words='english')),
        ('svm',LinearSVC())
    ])
    
    parameters=[
        {
            'vectorizer__max_features':[500,1000,1500],
            'random_forest__min_samples_split':[50,100,250,500]
        },
        {
            'vectorizer__max_features':[500,1000,1500],
            'svm__C':[1,3,5]
        }
    ]
    
    pipelines=[random_forest_pipeline,svm_pipeline]
    
    # gridsearch only for the Random Forest model
    grid_search_1 =GridSearchCV(pipelines[0],param_grid=parameters[0],cv=3,n_jobs=-1)
    grid_search_1.fit(X,y)
    
    # gridsearch only for the SVC model
    grid_search_2 =GridSearchCV(pipelines[1],param_grid=parameters[1],cv=3,n_jobs=-1)
    grid_search_2.fit(X,y)
    

    编辑

    如果您将模型明确定义到param_grid 列表中,则可以根据文档。

    链接:https://scikit-learn.org/stable/auto_examples/compose/plot_compare_reduction.html?highlight=pipeline%20gridsearch

    来自文档的代码:

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.datasets import load_digits
    from sklearn.model_selection import GridSearchCV
    from sklearn.pipeline import Pipeline
    from sklearn.svm import LinearSVC
    from sklearn.decomposition import PCA, NMF
    from sklearn.feature_selection import SelectKBest, chi2
    
    print(__doc__)
    
    pipe = Pipeline([
        # the reduce_dim stage is populated by the param_grid
        ('reduce_dim', 'passthrough'),
        ('classify', LinearSVC(dual=False, max_iter=10000))
    ])
    
    N_FEATURES_OPTIONS = [2, 4, 8]
    C_OPTIONS = [1, 10, 100, 1000]
    param_grid = [
        {
            'reduce_dim': [PCA(iterated_power=7), NMF()],
            'reduce_dim__n_components': N_FEATURES_OPTIONS,
            'classify__C': C_OPTIONS
        },
        {
            'reduce_dim': [SelectKBest(chi2)],
            'reduce_dim__k': N_FEATURES_OPTIONS,
            'classify__C': C_OPTIONS
        },
    ]
    reducer_labels = ['PCA', 'NMF', 'KBest(chi2)']
    
    grid = GridSearchCV(pipe, n_jobs=1, param_grid=param_grid)
    X, y = load_digits(return_X_y=True)
    grid.fit(X, y)
    

    【讨论】:

    • 我一直在关注这个视频youtube.com/watch?v=DHxsNrL7Zfw,作者是如何做到不出错的?
    • 在视频中,在 #17 单元格中,您可以看到一个循环 (for pipe in pipelines:),所以基本上它与我的答案相同
    • 我认为也可以使用单个 GridSearchCV 来完成。请检查我的答案。
    • 只有在您重新定义 parameters 列表中的模型时才可以。但是OP没有这种情况。反正我也报道过这个案子
    【解决方案2】:

    很有可能在单个Pipeline/GridSearchCV 中完成,基于示例here

    您只需明确提及管道的scoring 方法,因为我们最初并未声明最终估算器。

    例子:

    from sklearn.feature_extraction.text import CountVectorizer
    from sklearn.pipeline import Pipeline
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.svm import LinearSVC
    
    
    my_pipeline = Pipeline([
        ('vectorizer', CountVectorizer(stop_words='english')),
        ('clf', 'passthrough')
    ])
    
    
    parameters = [
        {
            'vectorizer__max_features': [500, 1000],
            'clf':[RandomForestClassifier()],
            'clf__min_samples_split':[50, 100,]
        },
        {
            'vectorizer__max_features': [500, 1000],
            'clf':[LinearSVC()],
            'clf__C':[1, 3]
        }
    ]
    
    grid_search = GridSearchCV(my_pipeline, param_grid=parameters, cv=3, n_jobs=-1, scoring='accuracy')
    grid_search.fit(X, y)
    
    grid_search.best_params_
    
    > # {'clf': RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
    #                         criterion='gini', max_depth=None, max_features='auto',
    #                         max_leaf_nodes=None, max_samples=None,
    #                         min_impurity_decrease=0.0, min_impurity_split=None,
    #                         min_samples_leaf=1, min_samples_split=100,
    #                         min_weight_fraction_leaf=0.0, n_estimators=100,
    #                         n_jobs=None, oob_score=False, random_state=None,
    #                         verbose=0, warm_start=False),
    #  'clf__min_samples_split': 100,
    #  'vectorizer__max_features': 1000}
    
    
    
    
    pd.DataFrame(grid_search.cv_results_)[['param_vectorizer__max_features',
                                           'param_clf__min_samples_split',
                                           'param_clf__C','mean_test_score',
                                           'rank_test_score']]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-12
      • 2021-08-11
      • 2017-11-28
      • 1970-01-01
      • 2021-11-26
      • 2019-05-19
      • 1970-01-01
      • 2020-12-29
      相关资源
      最近更新 更多