如何访问Scikit Learn嵌套交叉验证分数

4

我正在使用Python,并希望使用scikit learn进行嵌套交叉验证。我找到了一个非常好的示例

NUM_TRIALS = 30
non_nested_scores = np.zeros(NUM_TRIALS)
nested_scores = np.zeros(NUM_TRIALS)
# Choose cross-validation techniques for the inner and outer loops,
# independently of the dataset.
# E.g "LabelKFold", "LeaveOneOut", "LeaveOneLabelOut", etc.
inner_cv = KFold(n_splits=4, shuffle=True, random_state=i)
outer_cv = KFold(n_splits=4, shuffle=True, random_state=i)

# Non_nested parameter search and scoring
clf = GridSearchCV(estimator=svr, param_grid=p_grid, cv=inner_cv)
clf.fit(X_iris, y_iris)
non_nested_scores[i] = clf.best_score_

# Nested CV with parameter optimization
nested_score = cross_val_score(clf, X=X_iris, y=y_iris, cv=outer_cv)
nested_scores[i] = nested_score.mean()

如何从嵌套交叉验证中访问最佳参数集以及所有参数集(及其对应的分数)?
2个回答

7

您无法从cross_val_score中访问单个参数和最佳参数。 cross_val_score在内部的操作是克隆提供的估计器,然后对每个估计器使用给定的Xy调用fitscore方法。

如果您想要访问每个拆分点的参数,则可以使用:

#put below code inside your NUM_TRIALS for loop
cv_iter = 0
temp_nested_scores_train = np.zeros(4)
temp_nested_scores_test = np.zeros(4)
for train, test in outer_cv.split(X_iris):
    clf.fit(X_iris[train], y_iris[train])
    temp_nested_scores_train[cv_iter] = clf.best_score_
    temp_nested_scores_test[cv_iter] = clf.score(X_iris[test], y_iris[test])
    #You can access grid search's params here
nested_scores_train[i] = temp_nested_scores_train.mean()
nested_scores_test[i] = temp_nested_scores_test.mean()

在使用新数据进行预测时,我应该使用哪个模型(超参数)?这可能与OP的“最佳参数”请求有关。 - Paul
@Paul 请详细解释一下。最好提一个新问题。你可以使用GridSearchCV进行超参数调优。 - Vivek Kumar
每个 Grid Search 中的 clf.fit() 在 4 个内部循环中将返回不同的超参数集(4 组超参数)。当我希望对新的、未见过的数据进行预测时,我需要一些模型 M,并使用一些超参数进行拟合。我应该使用哪一个超参数集(或其他一些集合)来为模型 M 进行选择?我认为这个问题在这里提出:https://stats.stackexchange.com/q/319780我认为答案是,在完整数据上运行另一个独立的 Grid Search,如 https://stats.stackexchange.com/a/65158 的第二段所解释的那样。是这样吗? - Paul

1
Vivek Kumar的答案基于使用显式外部cv循环。如果OP想要访问基于sklearn的交叉验证工作流程的最佳估计器和最佳参数,我建议使用cross_validate而不是cross_val_score,因为前者允许您返回估计器。使用cross_validate的额外好处是您可以指定多个度量标准。
from sklearn.model_selection import cross_validate
scoring = {"auroc": "roc_auc"} # [1]
nested_scores = cross_validate(clf, X=X_iris, y=y_iris, cv=outer_cv, return_estimator=True, random_state=0)

然后您可以从每个交叉验证折中访问最佳模型:

best_models = nested_scores['estimator']
for i, model in enumerate(best_models):
    best_model = model.best_estimator_
    best_params = model.best_params_

请查看https://scikit-learn.org/stable/modules/model_evaluation.html#scoring-parameter以获取可用分数列表[1]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接