[转] 训练集,验证集和测试集
转自:https://testerhome.com/topics/11390
我们在模型训练的时候通常会将我们所得到的数据分成三部分。 分别是training set, dev set(也叫validation set)和 test set。 在我们的模型调研过程中,他们分别起着不同的作用。training set用来训练模型, dev set用来统计单一评估指标,调节参数, 选择算法。 test set 则用来在最后整体评估模型的性能。
三者之间的关系与作用
如上图,假设我们有一份数据,会将它按一定的规则进行拆分。其中training set和dev set分别输入到了逻辑回归算法中,而test set则是在模型训练结束后,被输入到模型中评估结果。 我们可以根据report来看一下他们各自的作用。 尤其是dev set和test set,在很多文章中对他们的介绍很模棱两可,让人搞不明白他们之间到底有什么区别。 给我的感觉就是写文章的人也不懂,在那里随便写写罢了。 我们先看training set和dev set,因为他们都被输入到了模型训练算法中。
上图是模型训练的report。 我们可以从中看到training set和dev set(图中叫验证集) 的auc指标。这里便引入了dev set的作用, training set 很好理解,训练模型用的。 而dev set的作用就是在这里很方便的评估算法的单一评估指标,在这里也就是auc,通过这个指标在training set和 dev set上的对比我们可以用来调整算法参数。 例如,如果training set的auc是0.9 而 dev set的auc确是0.6. 根据之前学到的我们很可能发生了过拟合的情况。 需要减少迭代次数或者设置L2正则来减少拟合。 又或者说我们发现训练AUC和验证AUC的数值都很低,例如只有0.6, 而loss(损失函数)仍然没有收敛,我们可能要增加迭代次数或者是扩大数据集或者改变特征。 这就是dev set的作用, 它是与training set一起被输入到模型算法中但又不参与模型训练,我们一边训练一边在dev set上看auc。这样相比于在test set上进行评估可以节省大量的时间。 我们在最开始的图中可以看到,使用test set会增加额外的步骤。 在我们调参阶段完全没有必要。只有当我们觉得当前的模型在dev set的效果已经差不多的时候,才会使用test set进一步验证模型性能。 那么dev set和training set有什么区别么? 看上去好像都是用来评估模型好坏的,特意在test set上进行验证又有什么用呢? 因为test set 能够提供更多的评估模型的指标。 我们之前说过评估一个分类器有混淆矩阵,有ROC,有召回,精准,F1 Scroe等。 这些都是在dev set上不做统计的,dev set上只统计单一评估指标,也就是AUC。 例如下面是test set的评估报告
总结一下
我们用training set做训练, dev set来初步评估结果,这里的评估结果是单一评估指标,也就是对模型来说最重要的一个指标,在这里我们使用AUC。 这么做的优点是dev set跟随training set一起被输入到模型算法中但又不参与模型训练。只是用来快速评估AUC的, 在调参阶段我们会不停的改变参数值来调整模型,而dev set就能帮助我们快速的查看结果。 相反的test set的作用并不是快速查看结果的,它提供一个模型的完整评估报告。可以更好的从多个维度评价模型的性能,但缺点是要做很多其他的操作,比较费时。我们一般在dev set上把参数调整的差不多后,才会使用到test set。
数据拆分的规则
数据量的拆分
现在我们知道要把数据拆分成3份,那么我们需要有一定的规则拆分数据集。 在老的规则里,也就是大数据时代之前。可能的规则是数据按照8:1:1来拆分。dev set和test set不能太小,小了不能很好的评估模型效果。 但这个规则是建立在数据集比较小的情况下,例如只有1w条数据或者更小。 在大数据时代小,我们一般面临的都是百万级甚至亿级的数据量。这时候的拆分规则就会变化一下。比如我们有一百万行的数据,那么这时候的拆分就不能按照8:1:1来了。 可能是98%:1%:1%的规则比较合适,因为百万级的数据即便只有1%也有一万行,用来评估模型效果已经有了比较不错的效果。把更多的数据留给training set来获得更好的模型是比较好的选择。
数据分布的拆分
我们的数据都是有业务含义的。 所以我们拆分的时候出了要考虑数据量以外可能还要考虑一些场景。 首先说dev set和test set,他们都是用来评估模型性能的,所以一定要保证他们的数据处于同一分布。 举个例子说,如果我们统计的是8个国家的数据,如果我们选择4个国家的数据作为dev set, 另外4个国家作为test set可以么? 这是明显不可以的,他们的数据处于不同的分布上。 如果我们在这样的dev set上进行调参并训练模型。 那到了test set上的时候你会发现模型效果极其的差。 所以我们要牢记于心的规则就是dev set和test set一定要处于同一分布。 在这里例子,我们要让dev set和test set随机的从所有国家中平均的抽取数据。 例如说每个国家有100份数据。 那么我们要保证dev set和test set能在每个国家中都随机抽取50份数据。
training set的抽取
那么traning set呢? 理论上traning set最好也是要跟dev set和test set处于同一分布的。但有些时候我们不能这么做,比如说我们的数据是有时序性的。例如预测点击率这种场景中,数据的时序性是很重要的。因为新闻,视频或者音频等资源的时效性比较强。 这时候如果让traning set 与dev set,test set处于同一分布就会有问题。 例如如果我们从数据中随机的拆分就会有问题。这样拆分甚至会出现用未来的数据预测过去的行为。 而我们希望的是用过去的数据预测未来的数据。 所以这时候我们应该做的是首先按时间把数据分成两类----过去的数据和未来的数据, 或者说是按一个时间点拆分成两种数据,处于这个时间点之前的数据作为traning set。 这个时间点之后的数据作为dev set和 test set。 这时候我们再按照上面的规则,保证dev set和test set处于同一分布就好了。 所以关于training set的选择要根据数据的业务场景来定。