嵌套交叉验证:cross_validate如何将GridSearchCV作为其输入估计量处理?

时间:2019-03-06 18:48:23

标签: python python-3.x scikit-learn nested cross-validation

以下代码将cross_validateGridSearchCV结合在一起,对虹膜数据集上的SVC执行嵌套的交叉验证。

(以下文档页面的修改示例: https://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html#sphx-glr-auto-examples-model-selection-plot-nested-cross-validation-iris-py。)


from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, cross_validate, KFold
import numpy as np
np.set_printoptions(precision=2)

# Load the dataset
iris = load_iris()
X_iris = iris.data
y_iris = iris.target

# Set up possible values of parameters to optimize over
p_grid = {"C": [1, 10],
          "gamma": [.01, .1]}

# We will use a Support Vector Classifier with "rbf" kernel
svm = SVC(kernel="rbf")

# Choose techniques for the inner and outer loop of nested cross-validation
inner_cv = KFold(n_splits=5, shuffle=True, random_state=1)
outer_cv = KFold(n_splits=4, shuffle=True, random_state=1)

# Perform nested cross-validation
clf = GridSearchCV(estimator=svm, param_grid=p_grid, cv=inner_cv, iid=False)
clf.fit(X_iris, y_iris)
best_estimator = clf.best_estimator_

cv_dic = cross_validate(clf, X_iris, y_iris, cv=outer_cv, scoring=['accuracy'], return_estimator=False, return_train_score=True)
mean_val_score = cv_dic['test_accuracy'].mean()

print('nested_train_scores: ', cv_dic['train_accuracy'])
print('nested_val_scores:   ', cv_dic['test_accuracy'])
print('mean score:            {0:.2f}'.format(mean_val_score))

cross_validate将每个折叠中的数据集分为培训和测试集。在每个折叠中,然后基于与折叠相关的训练集对输入估计量进行训练。此处输入的估算器是clf,它是参数化的GridSearchCV估算器,即再次对自身进行交叉验证的估算器。

关于整个问题,我有三个问题:

  1. 如果将clf用作cross_validate的估计量,是否(在GridSearchCV交叉验证过程中)将上述训练集进入子训练集和验证集,以确定最佳的超参数组合?
  2. 在通过GridSearchCV测试的所有模型中,cross_validate仅验证存储在best_estimator_属性中的模型吗?
  3. cross_validate是否完全训练了一个模型(如果是,为什么?)?还是直接通过测试集验证了存储在best_estimator_中的模型?

为更清楚地说明问题的含义,以下是我目前如何想象双重验证的说明。

enter image description here

1 个答案:

答案 0 :(得分:2)

  

如果将clf用作cross_validate的估计量,是否会将上述训练集分为子训练集和验证集,以便确定最佳超参数组合?

是的,如您所见here at Line 230,训练集再次被分为子训练和验证集(特别是line 240)。

更新是,当您将GridSearchCV分类器传递到cross-validate时,它将再次将训练集拆分为测试集和训练集。这里是a link的详细说明。您的图表和假设是正确的。

  

在通过GridSearchCV测试的所有模型中,cross_validate是否仅训练和验证存储在变量best_estimator中的模型?

是的,从答案herehere可以看出,GridSearchCV返回您情况下的best_estimator(因为refit参数默认为True情况。)但是,最好的估算器必须再次训练

  

cross_validate是否完全训练了一个模型(如果是,为什么?)?还是存储在best_estimator_中的模型直接通过测试集进行了验证?

根据您的第三个也是最后一个问题,是的,如果return_estimator设置为True,它将训练一个估计量并将其返回。参见this line。这是有道理的,因为在不首先训练估算器的情况下还应该返回分数吗?

更新 再次训练模型的原因是,交叉验证的默认用例并未假定您输入了具有最佳参数的最佳分类器。具体而言,在这种情况下,您正在从GridSearchCV发送分类器,但是如果您发送任何未经训练的分类器,则应该对其进行训练。我的意思是,是的,由于您已经在使用GridSearchCV并使用最佳估计器进行交叉验证,因此您不应再对其进行训练。但是,cross-validate无法知道这一点,因此,它假设您发送的是未经优化或未经训练的估算器,因此它必须再次对其进行训练并返回相同的分数。 / p>