1.在以往的机器学习中
如上图所示,以往机器学习中,对训练集、开发集、测试集的划分比例为60/20/20,如此划分通常可以获得较好的效果。
训练集(training set):训练算法。
开发集(development set):调整参数、选择特征,以及对学习算法作出其它决定。
测试集(test set):开发集中选出的最优的模型在测试集上进行评估。不会据此改变学习算法或参数。
2.大数据时代
在如今的大数据时代,我们通常可以获得庞大的数据集,比如1,000,000条数据,这种情况下,没有必要选择20%的数据量作为开发集,另外20%数据量作为测试集。通常我们选择10,000条数据作为开发集、10,000条数据作为测试集就足够了。即划分比例:98/1/1。因为开发集的目的是测试不同算法在其上的性能,选择性能更好的算法,因此开发集数量足够大足以评估不同算法并选择较优算法即可。同样地,测试集的目的是,给出最终的分类器,让你对它的性能有一个非常自信的估计。
3.训练集和测试集分布不一致的情况
比如你做了一个APP用于识别一张图片是否是狗狗。训练集使用的是来自网页的图片,而开发集和测试集可能是你的用户通过APP上传的图片。网页中的图片通常分辨率高、清晰;而用户上传的可能分辨率低、采光不好。很明显,训练集和测试集分布不一致。
只要确保:开发集和测试集服从同一分布。那么你会迭代的更快。
因为测试集和开发集分布不同的话,那么在开发集上表现良好的算法不一定在测试集上表现优异。如果是这种情况,那么大量针对开发集性能改进的工作将会是徒劳的。
如果你不是搞研究,而是想要在特定的机器学习应用上取得进展,建议尽可能选择服从相同分布的开发集和测试集数据。
4.没有测试集也ok(只有开发集)
测试集的目的是给你一个无偏估计(unbiased estimate)来评价最终选择的算法的性能。如果你不需要无偏估计,那么没有测试集也可以。
这种情况,你要做的就是:在训练集上训练算法,尝试不同的model architectures。然后在开发集上评估模型,迭代直到选择一个好的模型。
因为你在开发集上拟合数据,这样的话不会给你一个性能的无偏估计。如果你不需要的话,这样做完全没问题。
5.术语:大多数人习惯叫训练集和测试集,实际上应该叫训练集和开发集更准确
大多数人会把训练集叫做训练集,而把开发集叫做测试集,但是他们实际上做的事情是,把测试集当成了保留交叉验证集(hold-out cross validation set)。这种提法对术语的使用并不准确,因为测试集上会发生过拟合现象。
6.何时修改开发集、测试集和评价指标
在开发集上反复评估某个想法会导致算法在开发集上“过拟合”。当你完成开发后,应该在测试集上评估你的系统。如果你发现算法在开发集上的性能比测试集好得多,则表明你很有可能在开发集上过拟合了。这种情况下,你需要获取一个新的开发集。
不要根据测试集指标对算法做出任何决策,包括是否将系统回滚到前一周的状态。这样做会导致算法在测试集上开始过拟合,并且不要再指望通过测试集对你的系统性能进行完全无偏估计。
该指标不是项目应当优化的目标。假设你的狗狗 app 当前的指标为分类准确率,而该指标认为分类器 A 优于分类器 B。然而在
尝试了两种算法后,你发现分类器 A 竟然允许出现一些色情图片,这实在是难以容忍。应该怎么办呢?
此时的指标并不能辨别出算法 B 在实际产品中的表现是否比 A 更好,因此根据该指标来选择算法并不可靠,也说明此时应该改变现有的评估指标。你可以选择修改指标,使之对出现色情图片的情况执行严重惩罚。此外,强烈建议你选择一个新的指标并为你的团队制定一个新的研究目标,而不是在不可信的指标上耗费太多的时间,最终导致不得不回过头对分类器进行人工选择。