Python scikit通过多次重复学习GridSearchCV

Python scikit通过多次重复学习GridSearchCV,python,scikit-learn,cross-validation,grid-search,Python,Scikit Learn,Cross Validation,Grid Search,我正试图获得SVR模型的最佳参数集。 我想在C的不同值上使用GridSearchCV。 然而,从之前的测试中,我注意到训练/测试集的划分严重影响了整体性能(本例中为r2)。 为了解决这个问题,我想实现一个重复的5倍交叉验证(10x5cv)。是否有使用GridSearchCV执行此操作的内置方法 快速解决方案: 根据sci工具包中提出的想法,快速解决方案如下所示: NUM_TRIALS = 10 scores = [] for i in range(NUM_TRIALS): cv = K

我正试图获得SVR模型的最佳参数集。 我想在
C
的不同值上使用
GridSearchCV
。 然而,从之前的测试中,我注意到训练/测试集的划分严重影响了整体性能(本例中为r2)。 为了解决这个问题,我想实现一个重复的5倍交叉验证(10x5cv)。是否有使用
GridSearchCV
执行此操作的内置方法

快速解决方案:

根据sci工具包中提出的想法,快速解决方案如下所示:

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

这称为嵌套交叉验证。您可以查看以引导您进入正确的方向,也可以查看我的类似方法

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

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\u val\u score()和
GridSearchCV()说明嵌套交叉验证

  • clf=GridSearchCV(估计器,参数网格,cv=内部cv)
  • 通过
    clf、X、y、外部cv
    cross\u val\u分数
  • 如中所示,此
    X
    将使用
    outer\u cv
    分为
    X\u outer\u列车、X\u outer\u测试
    。y也一样
  • X_-outer_测试
    将被推迟,并且
    X_-outer_列
    将传递给clf进行拟合()(在我们的例子中为GridSearchCV)假设
    X_外部_序列
    从此被称为
    X_内部
    ,因为它被传递给内部估计器
    ,假设
    y_外部_序列
    y_内部
  • X_internal
    现在将使用网格搜索cv中的
    internal_cv
    分为
    X_internal_train
    X_internal_test
    。y也一样
  • 现在,gridSearch估计器将使用
    X\u inner\u train
    y\u train\u inner
    进行训练,并使用
    X\u inner\u test
    y\u inner\u test
    进行评分
  • 对于内部断路器(本例中为5),将重复步骤5和6
  • 所有内部迭代
    (X\u内部\u序列,X\u内部\u测试)
    的平均分数最好的超参数被传递给
    clf.best\u估计器
    ,并对所有数据进行拟合,即
    X\u外部\u序列
  • clf
    gridsearch.best_estimator_
    )然后将使用
    X_-outer_测试和
    y_-outer_测试进行评分
  • 对于外部测试(此处为10),将重复步骤3至9,并从
    交叉测试分数
  • 然后,我们使用mean()返回
    嵌套的_分数

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


    我不想要嵌套的CV,我只想重复CV 10次,每次使用不同的数据分割到训练集和测试集。据我所知,这就是
    外部CV
    所做的。它将把数据分成训练和测试10次(
    n_split
    ),并且
    cross_val_score
    将根据网格搜索(
    clf
    )对数据进行评分,网格搜索将把传递到其中的数据(即来自
    外部cv的训练数据
    )再次进入训练和测试,以找到最佳参数。你能给出一个你想实际做什么的例子吗?对于一组固定的参数,我想获得10个使用10个不同5CV计算的AUC值,以检查训练和测试集的不同划分对AUC值的影响。@VivekKumar非常感谢您的详细解释。您从中获取了示例,因此这似乎是一种常见的方法。嵌套交叉验证没有得到的一个方面是,为什么外部CV会触发网格搜索
    n_splits=10次。我希望外部CV只测试具有10个不同分割的最佳模型(具有固定参数)。这里,外部CV比较了10种不同的模型(可能有10组不同的PARAMs),这是有问题的。为了更好地理解,您的目标是重复5CV以查看SVR的行为方式。这意味着您将为每个参数组合使用10x5个不同的拆分?在任何情况下,您都可以提供一个自定义cv函数来实现这一点,并根据需要多次生成数据集拆分,或者根据需要对其进行自定义。GRIDSARCHCV将把它视为每次运行所选参数的运行,它会像往常一样在末尾收集结果。这对我来说不起作用。我得到以下错误:
    TypeError:“RepeatedKFold”对象不可编辑
    @tmastny我无法重现此错误。它与什么有关?也就是说,您的
    GridSearchCV
    是来自
    sklearn.model\u selection
    还是来自
    sklearn.grid\u search
    ?太棒了,它现在可以工作了。谢谢你的耐心。这绝对是最新的答案,并使重复的k折叠调整非常简单。这是惊人的,再加上我的一个:)这应该是正确的解决方案,而不是嵌套CV的解决方案
    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(...)