Python OneVsRestClassifier中估计器的网格搜索

Python OneVsRestClassifier中估计器的网格搜索,python,machine-learning,scikit-learn,Python,Machine Learning,Scikit Learn,我想在SVC模型中执行GridSearchCV,但这使用了一对一策略。对于后一部分,我可以这样做: model_to_set = OneVsRestClassifier(SVC(kernel="poly")) 我的问题是参数。假设我想尝试以下值: parameters = {"C":[1,2,4,8], "kernel":["poly","rbf"],"degree":[1,2,3,4]} 为了执行GridSearchCV,我应该执行以下操作: cv_generator = Stratif

我想在SVC模型中执行GridSearchCV,但这使用了一对一策略。对于后一部分,我可以这样做:

model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
我的问题是参数。假设我想尝试以下值:

parameters = {"C":[1,2,4,8], "kernel":["poly","rbf"],"degree":[1,2,3,4]}
为了执行GridSearchCV,我应该执行以下操作:

 cv_generator = StratifiedKFold(y, k=10)
 model_tunning = GridSearchCV(model_to_set, param_grid=parameters, score_func=f1_score, n_jobs=1, cv=cv_generator)
然而,当我执行它时,我得到:

Traceback (most recent call last):
  File "/.../main.py", line 66, in <module>
    argclass_sys.set_model_parameters(model_name="SVC", verbose=3, file_path=PATH_ROOT_MODELS)
  File "/.../base.py", line 187, in set_model_parameters
    model_tunning.fit(self.feature_encoder.transform(self.train_feats), self.label_encoder.transform(self.train_labels))
  File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 354, in fit
    return self._fit(X, y)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 392, in _fit
    for clf_params in grid for train, test in cv)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 473, in __call__
    self.dispatch(function, args, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 296, in dispatch
    job = ImmediateApply(func, args, kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/externals/joblib/parallel.py", line 124, in __init__
    self.results = func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/grid_search.py", line 85, in fit_grid_point
    clf.set_params(**clf_params)
  File "/usr/local/lib/python2.7/dist-packages/sklearn/base.py", line 241, in set_params
    % (key, self.__class__.__name__))
ValueError: Invalid parameter kernel for estimator OneVsRestClassifier
回溯(最近一次呼叫最后一次):
文件“/…/main.py”,第66行,在
argclass\u sys.set\u model\u参数(model\u name=“SVC”,verbose=3,file\u path=path\u ROOT\u MODELS)
文件“/…/base.py”,第187行,在set\u model\u参数中
model\u tunning.fit(self.feature\u encoder.transform(self.train\u feats),self.label\u encoder.transform(self.train\u labels))
文件“/usr/local/lib/python2.7/dist packages/sklearn/grid_search.py”,第354行
返回自适配(X,y)
文件“/usr/local/lib/python2.7/dist packages/sklearn/grid\u search.py”,第392行,in\u fit
对于列车网格中的clf_参数,在cv中进行测试)
文件“/usr/local/lib/python2.7/dist packages/sklearn/externals/joblib/parallel.py”,第473行,在调用中__
自我分派(功能、参数、kwargs)
文件“/usr/local/lib/python2.7/dist packages/sklearn/externals/joblib/parallel.py”,第296行,在分派中
作业=立即应用(func、args、kwargs)
文件“/usr/local/lib/python2.7/dist packages/sklearn/externals/joblib/parallel.py”,第124行,在__
self.results=func(*args,**kwargs)
文件“/usr/local/lib/python2.7/dist packages/sklearn/grid\u search.py”,第85行,在fit\u grid\u point中
clf.set_参数(**clf_参数)
文件“/usr/local/lib/python2.7/dist packages/sklearn/base.py”,第241行,在set_参数中
%(键,self.\类\名\名)
ValueError:估计器OneVsRestClassifier的参数内核无效
基本上,由于SVC位于OneVsRestClassifier中,而这是我发送给GridSearchCV的估计器,因此无法访问SVC的参数

为了实现我的目标,我看到了两种解决方案:

  • 在创建SVC时,以某种方式告诉它不要使用一对一策略,而是使用一对所有策略
  • 以某种方式指示GridSearchCV,参数对应于OneVsRestClassifier内的估计器 我还没有找到一种方法来做上述任何一种选择。你知道有没有办法做到这些吗?或者你可以建议另一种方法来达到同样的结果


    谢谢

    在网格搜索中使用嵌套估计器时,可以使用
    \uuu
    作为分隔符来确定参数的范围。在这种情况下,SVC模型作为名为
    estimator
    的属性存储在
    OneVsRestClassifier
    模型中:

    from sklearn.datasets import load_iris
    from sklearn.multiclass import OneVsRestClassifier
    from sklearn.svm import SVC
    from sklearn.grid_search import GridSearchCV
    from sklearn.metrics import f1_score
    
    iris = load_iris()
    
    model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
    
    parameters = {
        "estimator__C": [1,2,4,8],
        "estimator__kernel": ["poly","rbf"],
        "estimator__degree":[1, 2, 3, 4],
    }
    
    model_tunning = GridSearchCV(model_to_set, param_grid=parameters,
                                 score_func=f1_score)
    
    model_tunning.fit(iris.data, iris.target)
    
    print model_tunning.best_score_
    print model_tunning.best_params_
    
    这将产生:

    0.973290762737
    {'estimator__kernel': 'poly', 'estimator__C': 1, 'estimator__degree': 2}
    

    对于Python3,应该使用以下代码

    from sklearn.datasets import load_iris
    from sklearn.multiclass import OneVsRestClassifier
    from sklearn.svm import SVC
    from sklearn.model_selection import GridSearchCV
    from sklearn.metrics import f1_score
    
    iris = load_iris()
    
    model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
    
    parameters = {
        "estimator__C": [1,2,4,8],
        "estimator__kernel": ["poly","rbf"],
        "estimator__degree":[1, 2, 3, 4],
    }
    
    model_tunning = GridSearchCV(model_to_set, param_grid=parameters,
                                 scoring='f1_weighted')
    
    model_tunning.fit(iris.data, iris.target)
    
    print(model_tunning.best_score_)
    print(model_tunning.best_params_)
    

    您好,ogrisel,是否需要将OneVSRestClassifier与SVC一起使用?SVC本身不能处理多个目标值吗?OneVSRestClassifier可用于添加多标签支持。默认情况下,SVC只支持多类。还有本机多类impl。SVC基于OvO方案,但有点不同。@ogrisel在多标签分类的情况下(即,如果X、y由make_multilabel_分类生成),是否可以显示每个单独类别的最佳分数?在这个例子中,最好的分数0.97代表什么?它是由OneVsRestClassifier中的一个分类器评分的,还是三个分类器的平均值(因为iris数据集中有三个类)?如果你的onevsrest也是管道的一部分,您只需在管道中为onevsrest分类器指定的名称前面加上前缀。接受的代码为每个单独的模型选择相同的模型参数,这不是最优的。您应该使用grid_search为您试图预测的每个类确定最佳模型。不幸的是,这没有在sklearn中实现,因此您需要使用一个丑陋的循环。您应该添加一些解释以获得更好的答案。对于那些想知道发生了什么变化的人,只有您在实例化GridSearchCV时指定要使用的度量的方式不同
    from sklearn.datasets import load_iris
    from sklearn.multiclass import OneVsRestClassifier
    from sklearn.svm import SVC
    from sklearn.model_selection import GridSearchCV
    from sklearn.metrics import f1_score
    
    iris = load_iris()
    
    model_to_set = OneVsRestClassifier(SVC(kernel="poly"))
    
    parameters = {
        "estimator__C": [1,2,4,8],
        "estimator__kernel": ["poly","rbf"],
        "estimator__degree":[1, 2, 3, 4],
    }
    
    model_tunning = GridSearchCV(model_to_set, param_grid=parameters,
                                 scoring='f1_weighted')
    
    model_tunning.fit(iris.data, iris.target)
    
    print(model_tunning.best_score_)
    print(model_tunning.best_params_)