以下代码将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_
中的模型直接通过测试集验证?为了更清楚地表达问题的含义,下面是我如何想象目前双交叉验证的说明。
如果使用
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
没有办法知道这一点,因此,它假设您发送的是未经优化或未经训练的估算器,因此它必须再次训练并返回相同的分数。