2017-02-14 83 views
4

我试图获得SVR模型的最佳参数集。 我想使用GridSearchCV而不是C的不同值。然而,从之前的测试中我注意到,训练/测试集合higlhy影响整体性能(本例中为r2)。 为了解决这个问题,我想实施重复的5倍交叉验证(10 x 5CV)。是否有内置的方式使用GridSearchCV执行它?scikit-learn GridSearchCV具有多个重复

快速的解决方案:

NUM_TRIALS = 10 
scores = [] 
for i in range(NUM_TRIALS): 
    cv = KFold(n_splits=5, shuffle=True, random_state=i) 
    clf = GridSearchCV(estimator=svr, param_grid=p_grid, cv=cv) 
    scores.append(clf.best_score_) 
print "Average Score: {0} STD: {1}".format(numpy.mean(scores), numpy.std(scores)) 
+0

为了更好地理解,您的目标是重复5CV以了解SVR的行为方式?这意味着你将为每个参数组合使用10x5不同的分割?在任何情况下,您都可以提供自定义cv函数来执行此操作,并根据需要多次生成数据集分割,或根据需要对其进行自定义。 GridSearchCV会将它视为每次使用所选参数的运行,并且它将像往常一样在最后收集结果。 – mkaran

回答

6

这被称为嵌套cross_validation:

继在科幻试剂盒offical documentation提出的想法,一个快速的解决方案由下式表示。你可以看official documentation example引导你进入正确的方向,也可以看看我的other answer here类似的方法。

您可以调整的步骤,以满足您的需要:

svr = SVC(kernel="rbf") 
c_grid = {"C": [1, 10, 100, ... ]} 

# CV Technique "LabelKFold", "LeaveOneOut", "LeaveOneLabelOut", etc. 

# To be used within GridSearch (5 in your case) 
inner_cv = KFold(n_splits=5, shuffle=True, random_state=i) 

# To be used in outer CV (you asked for 10) 
outer_cv = KFold(n_splits=10, shuffle=True, random_state=i) 

# Non_nested parameter search and scoring 
clf = GridSearchCV(estimator=svr, param_grid=c_grid, cv=inner_cv) 
clf.fit(X_iris, y_iris) 
non_nested_score = clf.best_score_ 

# Pass the gridSearch estimator to cross_val_score 
# This will be your required 10 x 5 cvs 
# 10 for outer cv and 5 for gridSearch's internal CV 
clf = GridSearchCV(estimator=svr, param_grid=c_grid, cv=inner_cv) 
nested_score = cross_val_score(clf, X=X_iris, y=y_iris, cv=outer_cv).mean() 

编辑 - 嵌套的交叉验证与cross_val_score()GridSearchCV()说明

  1. CLF = GridSearchCV(估计,param_grid,CV = inner_cv)。
  2. 通行证clf, X, y, outer_cvcross_val_score
  3. 作为source code of cross_val_score看到,这X将使用outer_cv分为X_outer_train, X_outer_test。 y一样。
  4. X_outer_test将被阻止,并且X_outer_train将传递到clf for fit()(在我们的例子中为GridSearchCV)。 假设X_outer_train从这里开始被称为X_inner,因为它被传递给内部估计器,假设y_outer_trainy_inner
  5. X_inner现在将在GridSearchCV中使用inner_cv拆分为X_inner_trainX_inner_test。 y相同
  6. 现在,将使用X_inner_trainy_train_inner对网格搜索估算器进行训练,并使用X_inner_testy_inner_test对其进行评分。
  7. 步骤5和6对于inner_cv_iters(在这种情况下为5)将重复
  8. 将所有迭代的平均分数最好的参数传递到clf.best_estimator_并适用于所有数据,即X_train
  9. 然后使用X_outer_testy_outer_testclfgridsearch.best_estimator_)进行评分。
  10. 步骤3到9会反复为outer_cv_iters(10此处)和分数的数组将从cross_val_score
  11. 返回然后,我们使用均值()找回nested_score
+0

我不想嵌套CV,我只想重复CV 10次,每次使用不同的数据分割成训练和测试集。 –

+0

据我所知,这就是'outer_cv'正在做的事情。它会将数据分成训练和测试10次('n_split'),'cross_val_score'将对grid_search('clf')进行评分,然后分割传入的数据(即来自'outer_cv'的训练数据)再次进入火车并测试以找到最佳参数。 –

+0

你能举一个你想要做什么的例子吗? –

2

您可以向GridSearchCV提供不同的交叉验证生成器。二进制或多类分类问题的缺省值为StratifiedKFold。否则,它使用KFold。但你可以提供你自己的。在你的情况下,它看起来像你想要RepeatedKFoldRepeatedStratifiedKFold

from sklearn.model_selection import GridSearchCV, RepeatedStratifiedKFold 

# Define svr here 
... 

# Specify cross-validation generator, in this case (10 x 5CV) 
cv = RepeatedKFold(n_splits=5, n_repeats=10) 
clf = GridSearchCV(estimator=svr, param_grid=p_grid, cv=cv) 

# Continue as usual 
clf.fit(...) 
+0

这对我不起作用。我得到以下错误:'TypeError:'RepeatedKFold'对象不可迭代' – tmastny

+1

@tmastny我无法重现此错误。它与[这篇文章](https://stackoverflow.com/questions/43176916/typeerror-shufflesplit-object-is-not-iterable)有关吗?也就是说,你的'GridSearchCV'是来自'sklearn.model_selection'还是'sklearn.grid_search'? – AdamRH

+0

真棒,它现在有效。谢谢你的耐心。这绝对是最新的答案,并且使重复的k-fold调整非常简单。 – tmastny