【问题标题】:GridSearch for an estimator inside a OneVsRestClassifierGridSearch 用于 OneVsRestClassifier 中的估计器
【发布时间】:2012-09-19 22:11:07
【问题描述】:

我想在 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

基本上,由于 SVC 位于 OneVsRestClassifier 内,并且这是我发送到 GridSearchCV 的估算器,因此无法访问 SVC 的参数。

为了完成我想要的,我看到了两个解决方案:

  1. 在创建 SVC 时,以某种方式告诉它不要使用一对一策略,而是使用一对多策略。
  2. 不知何故指示 GridSearchCV 参数对应于 OneVsRestClassifier 内的估计器。

我还没有找到一种方法来做任何提到的替代方案。你知道是否有办法做到这些吗?或者您可以建议另一种方法来获得相同的结果?

谢谢!

【问题讨论】:

    标签: python machine-learning scikit-learn


    【解决方案1】:

    对于 Python 3,应使用以下代码

    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_)
    

    【讨论】:

    • 对于那些想知道发生了什么变化的人,只有在实例化 GridSearchCV 时指定要使用的指标的方式不同
    【解决方案2】:
    param_grid  = {"estimator__alpha": [10**-5, 10**-3, 10**-1, 10**1, 10**2]}
    
    clf = OneVsRestClassifier(SGDClassifier(loss='log',penalty='l1'))
    
    model = GridSearchCV(clf,param_grid, scoring = 'f1_micro', cv=2,n_jobs=-1)
    
    model.fit(x_train_multilabel, y_train)
    

    【讨论】:

    • 应该添加一些解释以做出更好的回答。
    【解决方案3】:

    当您使用带有网格搜索的嵌套估算器时,您可以使用__ 作为分隔符来限定参数。在这种情况下,SVC 模型在 OneVsRestClassifier 模型中存储为名为 estimator 的属性:

    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}
    

    【讨论】:

    • 嗨,ogrisel,是否需要将 OneVsRestClassifer 与 SVC 一起使用? SVC 不能自己处理多个目标值吗?
    • OneVsRestClassifer 可用于添加多标签支持。 SVC 默认只支持多类。也是原生的多类实现。 SVC 的基础是一个有点不同的 OvO 方案。
    • @ogrisel 是否可以在多标签分类的情况下显示每个单独类的最佳分数(即,如果 X,y 由 make_multilabel_classification 制作)?在这个例子中,最好的分数 0.97 代表什么,它是由 OneVsRestClassifier 中的一个分类器得分还是三个分类器的平均值(因为 iris 数据集中有三个类)?
    • 只是补充一点,如果你的 onevsrest 也是管道的一部分,你只需在管道中添加给 onevsrest 分类器的名称。
    • 接受的代码为每个单独的模型选择相同的模型参数,这不是最优的。您应该使用 grid_search 来确定您尝试预测的每个类的最佳模型。不幸的是,这在 sklearn 中没有实现,因此您需要使用丑陋的循环。
    猜你喜欢
    • 2012-12-22
    • 2020-03-02
    • 2020-07-14
    • 2016-01-03
    • 2016-02-20
    • 2020-02-03
    • 2020-01-15
    • 2018-12-27
    • 2020-01-03
    相关资源
    最近更新 更多