在 k 折交叉验证中,训练子样本是否包含测试集?

机器算法验证 交叉验证
2022-03-21 11:18:52

在此Wikipedia页面中的 K 折交叉验证小节中,它说“在 k 折交叉验证中,原始样本被随机划分为 k 个大小相等的子样本。在 k 个子样本中,保留一个子样本作为验证数据对模型进行测试,剩下的 k-1 个子样本作为训练数据”。测试数据根本不在图中。

而在我读过的一本书中,作者清楚地表明

  1. 完整的数据分为三组:训练集、测试集和验证集(或 Wikipedias 语言中的子样本)。
  2. 在 k 个子样本中,保留一个子样本作为验证数据,保留另一个子样本作为测试数据,并使用 k-2 个子样本作为训练数据。

哪个是真的?

2个回答

它们在各自的上下文中都是正确的。他们描述了在不同情况下两种不同的模型选择方式。

一般来说,当你在做模型选择和测试时,你的数据分为三个部分,训练集、验证集和测试集。您使用您的训练集来训练不同的模型,估计您的验证集的性能,然后选择具有最佳性能的模型并在您的测试集上对其进行测试。

另一方面,如果您使用 K 折交叉验证来估计模型的性能,那么您的数据将被分成 K 折,循环通过 K 折,每次使用一个折作为测试(或验证)设置并使用其余(K-1)折叠作为训练集。然后,您对所有折叠进行平均,以获得模型的估计测试性能。这就是维基百科页面所指的内容。

但请记住,这是为了测试特定模型,如果您有多个候选模型并且还想进行模型选择,则必须仅使用您的训练集选择模型以避免这种微妙的循环逻辑谬误. 因此,您进一步将 (K-1) 折叠“训练数据”分为两部分,一部分用于训练,另一部分用于验证。这意味着您首先进行额外的“交叉验证”以在 (K-1) 折中选择最佳模型,然后在测试折中测试此最佳模型。换句话说,您正在进行两级交叉验证,一个是一般的 K-fold 交叉验证,并且在每个交叉验证循环中,都有一个额外的 (K-1)-fold 交叉验证型号选择。然后你有你在问题中所说的内容,'在 k 个子样本中,一个子样本保留为验证数据,另一个子样本保留为测试数据,k-2 个子样本用作训练数据。

在这里,我以伪代码形式重新陈述我从@Yuanning 的答案和@cbeleites 的评论中收集到的内容。这可能对像我这样的人有帮助。

为了衡量一个确定模型的性能,我们只需要训练和测试集:

function measure_performance(model, full_test_set, k_performance):
    subset_list <- divide full_test_set into k_performance subsets
    performances <- empty array
    for each sub_set in subset_list:
        test_set <- sub_set
        training_set <- the rest of the full_test_set
        model <- train model with training_set
        performance <- test model with test_set
        append performance to performances
    end for each
    return mean of the values in peformances
end function

但是如果我们需要做模型选择,我们应该这样做:

function select_model(data, k_select, k_performance):
    subset_list <- divide data into k_select subsets
    performances <- empty array
    for each sub_set in subset_list:
        validation_set <- assume that this sub_set is validation set
        test_set <- one other random sub_set (Question: How to select test_set)
        training_set <- assume remaining as training set
        model <- get a model with the help of training_set and validation_set
        performance <- measure_performance(model,test_set, k_performance)
    end for each
    return model with the best performance (for this, performances will be scanned)
end function