如何划分训练集,验证集,测试集
训练集,验证集,测试集之间的区别
- 训练集(train set) —— 用于模型拟合的数据样本。
- 验证集(development set)—— 是模型训练过程中单独留出的样本集,它可以用于调整模型的超参数和用于对模型的能力进行初步评估。
在神经网络中, 我们用验证数据集去寻找最优的网络深度(number of hidden layers),或者决定反向传播算法的停止点或者在神经网络中选择隐藏层神经元的数量
在普通的机器学习中常用的交叉验证(Cross Validation) 就是把训练数据集本身再细分成不同的验证数据集去训练模型
- 测试集 —— 用来评估模最终模型的泛化能力。但不能作为调参、选择特征等算法相关的选择的依据。
类别 | 验证集 | 测试集 |
---|---|---|
是否用来训练 | 否 | 否 |
作用 | 用于调超参数,监控模型是否发生过拟合(以决定是否停止训练) | 为了评估最终模型泛化能力 |
使用次数 | 多次使用,以不断调参 | 仅仅一次使用 |
缺陷 | 模型在一次次重新手动调参并继续训练后所逼近的验证集,可能只代表一部分非训练集,导致最终训练好的模型泛化性能不够 | 测试集为了具有泛化代表性,往往数据量比较大,测试一轮要很久,所以往往只取测试集的其中一小部分作为训练过程中的验证集 |
为什么要测试集
训练集直接参与了模型调参的过程,显然不能用来反映模型真实的能力(防止课本死记硬背的学生拥有最好的成绩,即防止过拟合)。
验证集参与了人工调参(超参数)的过程,也不能用来最终评判一个模型(刷题库的学生不能算是学习好的学生)。
所以要通过最终的考试(测试集)来考察一个学(模)生(型)真正的能力(期末考试)。
但是仅凭一次考试就对模型的好坏进行评判显然是不合理的,所以接下来就要介绍交叉验证法
交叉验证法
交叉验证法的作用就是尝试利用不同的训练集/验证集划分来对模型做多组不同的训练/验证,来应对单独测试结果过于片面以及训练数据不足的问题。(就像通过多次考试,才通知哪些学生是比较比较牛B的)
交叉验证的做法就是将数据集粗略地分为比较均等不相交的k份
然后取其中的一份进行测试,另外的k-1份进行训练,然后求得error的平均值作为最终的评价
举个例子:假设建立一个BP神经网络,对于隐含层的节点数目,我们并没有很好的方法去确定。此时,一般将节点数设定为某一具体的值,通过训练集训练出相应的参数后,再由交叉验证集去检测该模型的误差;
然后再改变节点数,重复上述过程,直到交叉验证误差最小。
交叉验证算法的具体步骤如下:
随机将训练数据等分成k份,S1, S2, …, Sk。
对于每一个模型Mi,算法执行k次,每次选择一个Sj作为验证集,而其它作为训练集来训练模型Mi,把训练得到的模型在Sj上进行测试,这样一来,每次都会得到一个误差E,最后对k次得到的误差求平均,就可以得到模型Mi的泛化误差。
算法选择具有最小泛化误差的模型作为最终模型,并且在整个训练集上再次训练该模型,从而得到最终的模型。
K值的选择:
K值的选取是一个偏差与方差的权衡:
K=1时,所有数据用于训练,容易过拟合;
K=N时,相当于留一法LOOCV (Leave-one-out cross-validation ).
通常建议K=10
2017年的一项研究给出了另一种经验式的选择方法,作者建议
且保证
合理划分比例
过去,人们运用机器学习传统方法的时候,一般将训练集和测试集划为7:3
若有验证集,则划为6:2:2. 这样划分确实很科学,当数据量不大的时候(万级别及以下)
但到了大数据时代,数据量陡增为百万级别,此时我们不需要那么多的验证集和训练集
假设有100W条数据,只需要拿出1W条来当验证集,1W条来当测试集,就能很好地work了
因此,在深度学习中若是数据很大,我们可以将训练集、验证集、测试集比例调整为98:1:1