以下代码将cross_validate
与GridSearchCV
结合在一起,对虹膜数据集上的SVC执行嵌套的交叉验证。
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
估算器,即再次对自身进行交叉验证的估算器。
关于整个问题,我有三个问题:
clf
用作cross_validate
的估计量,是否(在GridSearchCV
交叉验证过程中)将上述训练集进入子训练集和验证集,以确定最佳的超参数组合?GridSearchCV
测试的所有模型中,cross_validate
仅验证存储在best_estimator_
属性中的模型吗?cross_validate
是否完全训练了一个模型(如果是,为什么?)?还是直接通过测试集验证了存储在best_estimator_
中的模型?为更清楚地说明问题的含义,以下是我目前如何想象双重验证的说明。
答案 0 :(得分:2)
如果将
clf
用作cross_validate
的估计量,是否会将上述训练集分为子训练集和验证集,以便确定最佳超参数组合?
是的,如您所见here at Line 230,训练集再次被分为子训练和验证集(特别是line 240)。
更新是,当您将GridSearchCV
分类器传递到cross-validate
时,它将再次将训练集拆分为测试集和训练集。这里是a link的详细说明。您的图表和假设是正确的。
在通过GridSearchCV测试的所有模型中,cross_validate是否仅训练和验证存储在变量best_estimator中的模型?
是的,从答案here和here可以看出,GridSearchCV返回您情况下的best_estimator(因为refit
参数默认为True
情况。)但是,最好的估算器必须再次训练
cross_validate是否完全训练了一个模型(如果是,为什么?)?还是存储在best_estimator_中的模型直接通过测试集进行了验证?
根据您的第三个也是最后一个问题,是的,如果return_estimator
设置为True
,它将训练一个估计量并将其返回。参见this line。这是有道理的,因为在不首先训练估算器的情况下还应该返回分数吗?
更新
再次训练模型的原因是,交叉验证的默认用例并未假定您输入了具有最佳参数的最佳分类器。具体而言,在这种情况下,您正在从GridSearchCV
发送分类器,但是如果您发送任何未经训练的分类器,则应该对其进行训练。我的意思是,是的,由于您已经在使用GridSearchCV
并使用最佳估计器进行交叉验证,因此您不应再对其进行训练。但是,cross-validate
无法知道这一点,因此,它假设您发送的是未经优化或未经训练的估算器,因此它必须再次对其进行训练并返回相同的分数。 / p>