首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何正确应用CrossValidation和/或拆分数据集?

如何正确应用CrossValidation和/或拆分数据集?
EN

Data Science用户
提问于 2020-01-17 07:57:04
回答 1查看 96关注 0票数 2

我有一个特殊的问题,现在还不知道如何正确地验证我在这个场景中的实验。

  • 有一个大数据集,包含100.000个样本,99.000 y=0,1.000 y=1。
  • 每个样本都有1.000个特征
  • 有10个不同的特征组合子集,它们必须进行评估才能获得关于或多或少表达性特征组的信息。
  • 由于每个子集的特性的数量和类型不同,必须手动确定适当的模型体系结构。
  • 必须对几种不同类型的模型的性能进行评估。
  • 必须对几种不同的采样技术的性能进行评估。
  • 必须采用10倍交叉验证。
  • 每个实验配置必须采用随机搜索(子集+模型+抽样技术的组合)。

这些事实导致了以下实验惯例:

代码语言:javascript
复制
train, val = splitDataset()
iterate each featureSubset:
    iterate each modelType:
        model = manuallySearchGoodArchitecture(featureSubset, modelType, train, val)

        iterate each samplingTechnique:
            train_temporary = applySampling(samplingTechnique)
            HPs = HPOptimization(model, train_temporary, val)
            result =  k-FOldCV(model, HPs, samplingTechnique, train)
        end
    end
end

所以,现在我不确定CrossValidation应用是否正确。因为需要验证的模型已经看到了train数据(在manuallySearchGoodArchitectureHPOptimization期间),这些数据也被用于CV期间的测试目的。

  1. 那么,这个例行公事有问题吗?
  2. 在应用适当的验证技术的同时,执行这些实验的正确方法是什么?
  3. 如何分割数据集?
EN

回答 1

Data Science用户

回答已采纳

发布于 2020-01-18 14:25:17

我不确定我是否理解这个过程的每一个部分,但有一个明显的问题:因为CV是应用在内部循环中的,因此对于其他参数(特征子集、模型类型、抽样技术),存在着过度拟合模型的严重风险。根据目标,这并不一定是错误的,但重要的是要相应地解释结果。例如,在这种情况下,结果将显示不同的特性子集如何在数据上执行,但是不同子集之间的性能差异不应该被认为是可靠的:可能某个特定子集碰巧比另一个子集更好。

这是一个相当复杂的设置,我认为需要考虑到效率方面的限制。如果可能的话,使用不同的数据子集进行几个阶段的CV (或其他技术,如套袋)可以获得最可靠的结果。例如,您可以运行整个过程几次,每次都使用不同的随机实例子集:通过这种方式,您可以平均性能,并查看一个特定的特性子集是否总是优于另一个特性子集(例如,其他参数的相同想法)。

编辑过的免责声明:我不知道是否有任何标准的方式来进行这样一个复杂的多层次设置,我的建议只是基于我与几个大致相似的案例的经验。

一般的想法是,每一个选择都可以被视为一个超参数,包括特征子集、模型类型、结构、采样技术。因此,我认为理想的情况是在每个级别交叉验证,即将每个循环级别都放在一个函数中,并使用不同的数据子集调用此函数k次。看起来就像这样:

代码语言:javascript
复制
train1, val1 = splitDataset()
iterate each featureSubset:
    train2, val2 = splitData(train1)
    resultTrain2 = kfoldCV(processLevel2, train2)
    resultLevel2 = apply(resultTrain2, val2)
resultLevel1 = apply(resultLevel2, val1)

processLevel2:
    iterate each modelType:
        train3, val3 = splitData(train2)
        resultTrain3 = kfoldCV(processLevel3, train3)
        ...

备注:我不能百分之百肯定这个算法,也许我把它弄得太复杂了.不过,我认为它给出了大致的想法。

但是当然,按照这个逻辑,计算的复杂性变得太高了,所以你可能需要走几条捷径。我在过去成功尝试过的一件事是使用遗传学习来同时优化不同的参数:这意味着有不同的“基因”代表不同的参数(特征子集、模型类型等),每一个参数都有自己的一组值,然后运行遗传过程,该过程应该收敛到所有参数的一组最优值(每次评估一个特定的参数组合时,我都使用CV )。但我也不知道这是否是一种非常正统的方法:)

edit2

经过更多的思考后,我想我会尝试做这样的事情:

代码语言:javascript
复制
innerData, valOuter = splitDataset() // keep large amount for validation set, say between 20-40%
train, valInner = splitDataset(innerData)
iterate each featureSubset:
    iterate each modelType:
        model = manuallySearchGoodArchitecture(featureSubset, modelType, train, val)

        iterate each samplingTechnique:
            train_temporary = applySampling(samplingTechnique)
            HPs = HPOptimization(model, train_temporary, valInner)
            result =  k-FOldCV(model, HPs, samplingTechnique, train)
        end
    end
end

bestHPCombinations = select top N HPCombinations from first stage
for each HPCombination in bestHPCombinations
     model = train(innerData)
     result = apply(model, valOuter)
end

它更简单:这个想法只是重新评估一些新数据的第一阶段的结果,以避免过度使用(这里HPCombination包括featuresSubset、modelType等)。第二阶段还可以包括CV或套袋,以获得更可靠的结果。但总的来说,我认为这一选择是合理可靠的,因为从第一阶段的最佳模式也不太可能是最好的模式在第二阶段只是偶然。

票数 1
EN
页面原文内容由Data Science提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://datascience.stackexchange.com/questions/66616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档