Scikit Learn GridSearchCV 和 pipeline 使用不同的方法

Posted

技术标签:

【中文标题】Scikit Learn GridSearchCV 和 pipeline 使用不同的方法【英文标题】:ScikitLearn GridSearchCV and pipeline using different methods 【发布时间】:2020-09-02 12:01:27 【问题描述】:

我正在尝试使用 GridSearchCV 和管道将这些机器学习方法评估为相同的数据,当我在相同的方法中改变参数时它可以工作,但是当我放置多个方法时它会出错

pipe_steps = [
    ('scaler', StandardScaler()), 
    ('logistic', LogisticRegression()),
    ('SVM',SVC()),
    ('KNN',KNeighborsClassifier())]
check_params=
    'logistic__C':[1,1e5],
    'SVM__C':[1,1e5],
    'KNN__n_neighbors':[3,5],
    'KNN__metric':['euclidean','manhattan']
    
pipeline = Pipeline(pipe_steps)
GridS = GridSearchCV(pipeline, param_grid=check_params)
GridS.fit(X, y)
print('Score %3.2f' %GridS.score(X, y))
print('Best Fit')
print(GridS.best_params_)

在下面的管道上给出错误消息

TypeError                                 Traceback (most recent call last)
<ipython-input-139-75960299bc1c> in <module>
     13     
     14 
---> 15 pipeline = Pipeline(pipe_steps)
     16 
     17 BCX_Grid = GridSearchCV(pipeline, param_grid=check_params)

C:\ProgramData\Anaconda3\lib\site-packages\sklearn\pipeline.py in __init__(self, steps, memory, verbose)
    133     def __init__(self, steps, memory=None, verbose=False):
    134         self.steps = steps
--> 135         self._validate_steps()
    136         self.memory = memory
    137         self.verbose = verbose

C:\ProgramData\Anaconda3\lib\site-packages\sklearn\pipeline.py in _validate_steps(self)
    183                                 "transformers and implement fit and transform "
    184                                 "or be the string 'passthrough' "
--> 185                                 "'%s' (type %s) doesn't" % (t, type(t)))
    186 
    187         # We allow last estimator to be None as an identity transformation

TypeError: All intermediate steps should be transformers and implement fit and transform or be the string 'passthrough' 'LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='warn', n_jobs=None, penalty='l2',
                   random_state=None, solver='warn', tol=0.0001, verbose=0,
                   warm_start=False)' (type <class 'sklearn.linear_model.logistic.LogisticRegression'>) doesn't


谢谢

【问题讨论】:

您希望使用多个分类器进行网格搜索吗?喜欢同时使用 SVC、KNN 和 LogisticRegression 进行网格搜索? 这正是我想要的! 我已经发布了答案,请查看;D 【参考方案1】:

您需要将管道拆分为多个管道,因为我有一个解决方案,需要一个网格参数列表来确定管道的每个步骤。

pipeline = Pipeline([
    ('transformer', StandardScaler(),),
    ('model', 'passthrough',),
])

params = [
    
        'model': (LogisticRegression(),),
        'model__C': (1, 1e5,),
    ,
    
        'model': (SVC(),),
        'model__C': (1, 1e5,),
    ,
    
        'model': (KNeighborsClassifier(),),
        'model__n_neighbors': (3, 5,),
        'model__metric': ('euclidean', 'manhattan',),
    
]

grid_Search = GridSearchCV(pipeline, params)

使用此策略,您可以动态定义管道的步骤。

【讨论】:

谢谢贝尔纳多!!!它起作用了,我只需要按照程序的要求定义:scoring = 'accuracy' grid_Search = GridSearchCV(pipeline, params,scoring = 'accuracy') 非常好!!!【参考方案2】:

您的问题不是正确定义的超参数。问题是所有中间步骤都应该是transformers,如错误所示。在您的管道中SVM 不是变压器。

看到这个post

【讨论】:

那么,我该如何实现呢? 从技术上讲,无论是什么类,它都应该有一个.transform() 方法*和一个简单的.fit_transform() 作为拟合和变换方法链。因此,如果您从 SVC 继承一个类并为它编写一个转换方法,那就可以了。然后您返回下一步所需的 X:您的 KNN。请注意,Y 按原样提供给变压器的下一步,没有变化 或者您可以开始编写自己的转换器(标准方式)并在其中调用 SVC。在此掠夺:scikit-learn.org/stable/modules/generated/…

以上是关于Scikit Learn GridSearchCV 和 pipeline 使用不同的方法的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn GridSearchCV 弃用警告

Scikit-learn 中的 GridSearchCV 输出问题

scikit-learn 中 LogisticRegression 上的 GridSearchCV

Scikit-Learn:GridSearchCV 的自定义损失函数

为啥 scikit-learn 中的 GridSearchCV 会产生这么多线程

Scikit-learn 多输出分类器使用:GridSearchCV、Pipeline、OneVsRestClassifier、SGDClassifier