如何帮助确保测试数据不会泄漏到训练数据中?


60

假设我们有一个人建立了预测模型,但是不一定有人对适当的统计或机器学习原理很精通。也许我们正在帮助那个人在学习中,或者那个人正在使用某种需要最少知识的软件包。

现在,这个人可能会很好地认识到真正的测试来自样本外数据的准确性(或其他任何度量标准)。但是,我担心的是,这里有很多微妙的问题要担心。在简单的情况下,他们建立模型并根据训练数据对其进行评估,并根据保留的测试数据对其进行评估。不幸的是,有时返回该位置并调整一些建模参数并检查相同“测试”数据的结果有时太容易了。此时,数据不再是真正的样本外数据,过拟合可能会成为问题。

解决此问题的一种可能方法是建议创建许多样本外数据集,以使每个测试数据集在使用后都可以丢弃,而根本无法再使用。但是,这需要大量的数据管理,尤其是必须在分析之前完成拆分(因此,您需要事先知道有多少拆分)。

也许更常规的方法是k倍交叉验证。但是,从某种意义上讲,我认为“训练”和“测试”数据集之间的区别会消失,特别是对于那些仍在学习的人。同样,我也不认为这对所有类型的预测模型都有意义。

有什么方法可以被我忽略,以帮助克服过度安装和测试泄漏的问题,同时仍然对没有经验的用户保持一定的了解?


迈克尔,我关闭了ML网站上的重复线程,并在此处合并了答案。请随时编辑此问题,以反映您要进行的任何更改-我不想进行此操作,因为会无意间更改您的意思。
ub

这个问题很老,答案可以接受,但是我不能不明白最初的前提似乎是矛盾的。如果这是关于学习练习的,那么最好的方法是让他们失败,并建立一个过拟合模型,该模型随后无法很好地预测。(也许有一个秘密的保持数据集,向您显示了他们的方式的错误。)但这听起来也像是您有不合格的人在制作模型,有人会认真对待并采取行动,并且您正试图将损失降到最低。一臂长。正如您所说,有很多微妙之处。
韦恩

Answers:


50

没错,这是机器学习/统计建模中的重要问题。本质上,真正解决此问题的唯一方法是保留独立的测试集,并保持其状态直到研究完成,然后将其用于最终验证。

但是,人们不可避免地会在测试集中查看结果,然后相应地更改其模型。但是,这不一定会导致泛化性能的提高,因为不同模型的性能差异可能很大程度上归因于我们拥有的特定测试数据样本。在这种情况下,我们在做出选择时实际上是过度拟合了测试误差。

限制这种情况的方法是使测试误差的方差尽可能小(即,如果我们使用不同的数据样本作为测试集(从相同的基础分布中提取),则会看到测试误差的差异)。如果可能的话,使用大型测试集最容易做到这一点,如果没有太多可用数据,则使用自举或交叉验证。

我发现,模型选择中的这种过度拟合要比普遍认为的要麻烦得多,尤其是在性能估计方面,请参见

GC Cawley和NLC Talbot,模型选择中的过拟合和性能评估中的后续选择偏差,《机器学习研究期刊》,2010年。2010年7月,第11页,第2079-2107页(www)

这种问题尤其会影响已在许多研究中使用的基准数据集的使用,并且每个新研究都受到早期研究结果的隐式影响,因此观察到的性能可能是对真实数据的过度乐观估计。方法的性能。我设法解决此问题的方法是查看许多数据集(因此该方法未调整到一个特定的数据集),并且还使用多个随机测试/训练拆分来进行性能估计(以减少估计的方差)。但是,结果仍然需要警告这些基准已经过拟合。

发生这种情况的另一个示例是在基于验证集的排行榜中进行的机器学习竞赛。不可避免地,一些竞争者会不断修改自己的模型,以进一步提高排行榜的排名,但最终却跌至最终排名的底部。这样做的原因是,他们的多种选择都使验证集过拟合(有效地学习了小型验证集中的随机变化)。

如果您无法保留统计上纯的测试集,那么恐怕两个最佳选择是(i)收集一些新数据以创建新的统计上纯的测试集,或者(ii)提出新模型基于的警告观察测试设置误差后做出的选择,因此性能估计可能会产生乐观偏差。


1
+1对我的经验和如何有效地回答这个问题印象深刻。
whuber

3
欢呼加油,这已经是我几年来的主要研究课题,而且我发现许多广泛用于机器学习的模型选择程序非常脆弱,并且对其进行的评估越彻底,它们的工作效果就越差。机器学习中使用的许多方法没有比旧的更简单的方法更好地工作,这并不奇怪,这仅仅是因为性能评估中使用了偏向模型的选择过程。这个问题确实是一个很好的问题,重要的是不要自己动手做模型选择程序的一部分!
Dikran有袋动物

很有意思。(我也对问题本身表示不赞成,因为您的答复使我更好地理解了它。)
whuber

2
(+1)不错的回应。其产生到检测准确性的过分乐观的措施对同一数据集使用多个分类器已经在已经讨论的最优分类器选择及在错误率估计负偏压:高维预测的实证研究,BMC MRM 2009,9:85 (此处有一些PDF幻灯片),以及分类规则比较中的多规则偏差中的其他讨论(Yousefi等人,Bioinformatics 2011,27(12):1675)。
chl

感谢您提供论文的链接,它们看起来很有趣。
Dikran有袋动物博物馆,

15

确保这一点的一种方法是确保您已对所有适合模型的工作进行了编码,甚至是“修补”。这样,当您重复运行流程(例如通过交叉验证)时,可以使运行之间保持一致。这样可以确保通过交叉验证过程捕获所有潜在的变异源。

另一个至关重要的事情是确保两个数据集中都有代表性的样本。如果您的数据集不能代表您期望用来预测的数据类型,那么您将无能为力。所有建模都基于“归纳法”起作用的假设-我们未观察到的事物的行为类似于我们所观察到的事物。

一般来说,除非(i)您知道自己在做什么,并且(ii)您尝试过较简单的方法,发现它们不起作用,以及复杂方法如何解决问题,否则请远离复杂的模型拟合过程。简单方法的问题。“简单”和“复杂”是指对进行装配的人而言“简单”或“复杂”的意思。之所以如此重要,是因为它允许您将我喜欢的“嗅探测试”应用于结果。结果看起来正确吗?您无法“闻”到您不了解的过程的结果。

注意:我的答案的下一个相当长的部分是基于我的经验,该经验位于 区域,其中可能很大。我几乎可以肯定,下面接下来将不适用于的情况下N>>p p Np N<p

当您有大量样本时,只要您的建模不太“局部”,使用和不使用给定观察值之间的差异就很小。这是因为给定数据点的影响通常是的顺序。因此,在大型数据集中,从“提供”测试数据集中获得的残差与在训练数据集中使用它获得的残差基本相同。您可以使用普通的最小二乘法来显示。从第个观察值中排除后得到的残差(即,如果将观察值放入测试集中将导致测试集错误)是,其中是训练残差,1Nieitest=(1hii)1eitraineitrainhii是第个数据点的杠杆作用。现在我们有了,其中是回归中变量的数量。现在,如果,那么要使足够大而在测试集和训练集误差之间产生可观的差异是非常困难的。我们可以举一个简化的例子,假设(截距和变量),设计矩阵是(训练集和测试集),杠杆是iihii=ppN>>phiip=21N×pX

hii=xiT(XTX)1xi=1Nsx2(1xi)(x2¯x¯x¯1)(1xi)=1+x~i2N

其中,和。最后,是标准化的预测变量,它测量与平均值有多少标准偏差。因此,我们从一开始就知道测试集误差将比训练集“边缘”观察的训练集误差大得多。但这基本上又是代表问题了-“边缘”的观测比“中间”的观测更不具有代表性。另外,这是为了订购。因此,即使您有观测值,即使x¯=N1ixix2¯=N1ixi2sx2=x2¯x¯2x~i=xix¯sxxi1N100x~i=5(在大多数定义中x空间的离群值),这意味着,并且测试错误被低估了仅为。如果您有一个大数据集,例如,那么它甚至会更小,,小于。实际上,对于观测值,您将需要的观测值,以便使用训练集误差使测试集误差低估。hii=26100126100=7410010000126100001%10000x~=5025%

因此,对于大数据集,使用测试集不仅效率低下,而且只要也是没有必要的。这适用于OLS,也适用于GLM(GLM的详细信息不同,但总体结论是相同的)。在多于尺寸,“异常值”通过用大的“主成分”的分数的观察中定义。这可以通过写其中是的(正交)特征向量矩阵,特征值矩阵。我们得到其中N>>p2hii=xiTEET(XTX)1EETxiEXTXΛhii=ziTΛ1zi=j=1pzji2Λjjzi=ETxi是的主成分分数。xi

如果您的测试集有观测值,则得到矩阵版本,其中和是测试集中设计矩阵的行。因此,对于OLS回归,您已经知道对于所有可能的将数据拆分为训练集和测试集的“测试集”错误。在这种情况下(),根本不需要拆分数据。您可以报告几乎所有大小的“最佳情况”和“最坏情况”测试集错误,而无需实际拆分数据。这样可以节省大量PC时间和资源。ke{k}test=(IkH{k})1e{k}trainH{k}=X{k}(XTX)1X{k}TX{k}N>>p

基本上,所有这些都简化为使用惩罚项,以解决训练和测试错误(例如BIC或AIC)之间的差异。这样可以有效地获得与使用测试集相同的结果,但是您不会被迫丢弃可能有用的信息。使用BIC,您可以近似模型的证据,数学上看起来像:

p(D|MiI)=p(y1y2yN|MiI)

请注意,在此过程中,我们无法估计任何内部参数- 必须完全指定每个模型或集成其内部参数。但是,通过重复使用乘积规则,然后取结果日志,我们可以使它看起来像交叉验证(使用特定损失函数)。Mi

p(D|MiI)=p(y1|MiI)p(y2yN|y1MiI)
=p(y1|MiI)p(y2|y1MiI)p(y3yN|y1y2MiI)
==i=1Np(yi|y1yi1MiI)
log[p(D|MiI)]=i=1Nlog[p(yi|y1yi1MiI)]

这暗示了一种交叉验证的形式,但是在不断更新训练集的情况下,一次从测试集中进行一次观察-与卡尔曼滤波器类似。我们使用当前训练集从测试集中预测下一个观察值,使用条件对数似然法测量与观察值的偏差,然后更新训练集以包括新观察值。但是请注意,此过程将完全消化所有可用数据,同时确保将每个观察结果均作为“样本外”情况进行测试。它也是不变的,因为您所说的“观测1”或“观测10”无关紧要;结果是相同的(某些排列的计算可能比其他排列更容易)。损失函数也是“自适应的”,因为如果我们定义大号Li=log[p(yi|y1yi1MiI)],则的清晰度取决于,因为损失函数会不断用新数据进行更新。Lii

我建议以这种方式评估预测模型会很好。


4
+1-很好的建议和关于杠杆作用的有趣讨论(适用于大型数据集)。我倾向于使用较小的数据集,这些数据集可能会过度拟合,在这种情况下,通常很容易过度拟合边际可能性(“证据”),最终得出的模型比开始时要差。我怀疑AIC和BIC同样“脆弱”。从根本上说,优化是统计中万恶之源,因为基于有限样本进行的任何选择或调整的参数都会引入过度拟合的可能性。边缘化要安全得多,但是通常计算量很大。
2011年

2
+1-特别是在第三段(首先使用简单方法)。提醒您良好的帕累托规则。如果机器学习者在发布自己的尝试不足以证明其新算法的优越性之前牢记这一点……
steffen 2011年

8

我想保证这一点的唯一方法是让其他人拥有测试数据。在客户与顾问的关系中,这可以很容易地进行管理:客户向顾问提供了用于建立模型的训练集,并且在该训练集中,顾问可以以任何必要的方式分割数据,以确保不会过度拟合发生; 随后,将模型返回给客户端以用于其测试数据。

对于单个研究人员而言,有理由认为,最佳实践就是模仿这种设置。这意味着在完成所有模型选择之后,提取一些数据进行测试。不幸的是,正如您所说,这不是很多人都实践的,甚至应该发生在应该更了解的身上!

但是,最终取决于模型的用途。如果您只对单个数据集的预测感兴趣,那么您可能会过度拟合自己喜欢的所有数据?但是,如果您试图将模型推广为具有良好概括性的模型,或者在某些实际应用中使用该模型,那么这当然具有重要意义。

我想提一个附带的问题,那就是即使您正确地遵循了所有步骤,由于数据不是真正的iid,您仍然可以得到过拟合的模型。例如,如果数据中存在时间相关性,那么如果您从时间1-3中获取所有训练数据,并在时间4上进行测试,则可能会发现预测误差大于预期值。备选地,可能存在特定于实验的伪像,例如所使用的测量设备或人体实验中的对象库,这些伪像导致模型的通用性差于预期。


是的,我知道创建一个真正的样本外数据集非常困难,因为很容易意外地导致时间相关,而没有时间相关。
Michael McGowan

1
一些公司将其作为策略来执行,例如通过相应地设置数据库view权限来实现,其中一些团队是测试数据专用的,而其他团队是测试数据盲的。
ijoseph '18 -10-9

6

这是一个很好的问题,也是一个非常微妙的问题。当然,还有一些故意欺骗的错误,这些错误源于试图欺骗您的人。但是,还有一个更深层次的问题,即如何避免意外泄漏和避免诚实的错误。

让我列出一些操作上的良好做法。它们全都源于我在某些时候犯的诚实错误:

  • 将您的数据分为三类:训练,验证和测试。
  • 了解问题的设置,以便能够争论什么是合理的,什么不是合理的。理解了这个问题,很多时候对数据表示的细微误解会导致泄漏。例如,虽然没有人会在一个视频的同一帧上进行训练和测试,但是当同一视频的两个帧以不同的折叠度落下,同一视频的两个帧可能共享相同的人并具有相同的照明效果时,这会更加微妙。 。
  • 使用先前编写的交叉验证程序要格外小心。如果不是您自己写的,则更多(LIBSVM在这里是一个大罪犯)。
  • 报告任何内容之前,至少要重复两次实验,即使是报告给办公室伴侣也是如此。在进行实验提交并写下您正在运行的代码的版本之前,版本控制是您的朋友。
  • 规范化数据时要非常小心。很多时候,这会导致您想同时拥有要在其上进行测试的完整数据集,而这通常又是不现实的。

有一个关于训练/评估集的问题,我在machinelearning.stackexchange.com/a/196/114上对此进行了理论概述-解释了分层保持,k折交叉验证和重复实验。在我的教育者看来,这些方法完全解决了上述问题,其余的只是“老师的问题”。另外,您列表中的所有做法似乎都可以解决“草率的,不可接受的错误”,而且我看不到那里的任何细微之处。我非常想知道我在想什么-您能发表评论吗?
andreister

我同意它们全都来自草率。我还提到过它们根本不是理论上的(已经说过它们是可操作的)。我已经编辑了我的帖子。
carlosdc

5

已经给出的出色答案涵盖了许多重要点。

最近,我开发了此个人检查表以确保测试数据的统计独立性:

  • 在数据层次结构的最高级别拆分数据(例如,按患者拆分)
  • 对于已知或怀疑的混杂因素,也独立进行拆分,例如仪器的日常变化等。
  • (美国能源部应注意随机测量序列**)
  • 在重新采样验证中,需要针对每个替代模型重做涉及第一步(通常是预处理)的涉及所有一个以上患者*的所有计算步骤。对于保留/独立测试集验证,需要此步骤之前将测试患者分开。
    • 这与计算是否被称为预处理还是被视为实际模型的一部分无关。
    • 典型的罪魁祸首:平均居中,方差缩放(通常只有轻微的影响),降维(例如PCA或PLS)(可能导致严重偏差,例如,低估了一个错误的数量级)
  • 任何一种数据驱动的优化或模型选择都需要另一个(外部)测试来独立验证最终模型。
  • 概括性能的某些类型只能通过特定的独立测试集来衡量,例如,对于将来测得的情况,预测性能将如何下降(我不处理时间序列预测,而只涉及仪器漂移)。但这需要适当设计的验证研究。
  • 在我的领域中还有另一种特殊的数据泄漏类型:我们对生物组织进行空间分辨光谱分析。即使试图使用聚类分析然后仅找出每个聚类属于哪一类(那将是半监督的测试数据,但不是完全独立)。

  • 最后但并非最不重要的一点:在对重采样验证进行编码时,我实际上检查了计算到数据集中的索引是否不会导致从训练患者,天数等方面获取测试行。

请注意,声称使用独立测试集的测试也可能发生“为了确保独立性而未进行拆分”和“在涉及多个案例的任何计算发生之前进行拆分”,即使数据分析师使用不了解测试用例的参考。如果在给出最终模型之前保留测试数据,则不会发生这些错误。

*为了便于描述,我将患者用作数据中的最高层次结构。
**我是分析化学家:仪器漂移是一个已知问题。实际上,化学分析方法验证的一部分是确定需要多长时间对一次验证样品进行校准检查,以及多久重新进行一次校准。


FWIW:实际上,我在

  • p的数量级为,102103
  • pnrows通常大于,但是p
  • Ñ p 一个ë Ñ 小号 « p 10 0 - 10 1 10 2nbiol.replicates或为(数量级:,很少)npatientsp100101102
  • 根据光谱测量方法的不同,一个人的所有行(例如患者)可能非常相似或相异,因为不同类型的光谱的信噪比(仪器误差)也相差一个数量级左右。

就我个人而言,我还没有遇到过用于分类器开发的应用程序,在该应用程序中我获得了足够的独立案例,可以搁置适当的独立测试集。因此,我得出的结论是,在该方法仍处于开发阶段时,正确完成重采样验证是更好的选择。最终需要进行正确的验证研究,但是这样做会浪费大量资源(或者由于差异而导致结果将不包含有用的信息),而在方法开发仍处于变化的阶段时,这样做是非常必要的。


2

如果我没记错的话,某些预测竞赛(例如Netflix或Kaggle上的竞赛)使用以下方案:

有一个带有“答案”的训练集。有测试集#1,研究人员为此提供了答案。研究人员找出他们的分数。有测试集#2,研究人员为此提供了答案,但研究人员并未找到他们的分数。研究人员不知道在#1和#2中有哪些预测案例。

在某些时候,第2组必须可见,但是您至少已限制了污染。


2

在某些情况下,例如基于生物学序列的预测变量,仅确保病例不出现在一组以上是不够的。您仍然需要担心集合之间的依赖性。

例如,对于基于序列的预测变量,需要通过确保不同集合(包括不同的交叉验证集合)中的序列不共享高度的序列相似性来消除冗余。


2

从理论的角度来看,我会说“ k-fold交叉验证”是正确的答案,但是您的问题似乎更多是关于组织和教学方面的问题,因此我将以不同的方式回答。


人们在“还在学习”时,通常会认为他们正在学习如何“快速而肮脏地” 应用算法和所有“额外”知识(问题动机,数据集准备,验证,错误分析,实际问题等等)。 )将在“准备更充分”时被“以后”学习。

这是完全错误的。

  1. 如果我们希望学生或任何人了解测试集和训练集之间的区别,最糟糕的事情是将这两个集交给两个不同的人,好像我们认为“现阶段”的“额外知识”是有害。这就像软件开发中的瀑布式方法一样-数月的纯设计,数月的纯编码,数月的纯测试以及最后的遗憾。

  2. 学习不应该是瀑布。学习的所有部分-问题动机,算法,实际难题,结果评估-必须分小步走到一起。(类似于软件开发中的敏捷方法)。

也许这里的每个人都经历过安德鲁·伍(Andrew Ng)的ml - class.org-我以他的课程为例,它是一种强大的“敏捷”的学习方式(如果您愿意的话),一种学习风格-永远不会提出“如何做到”的问题。确保测试数据不会泄漏到训练数据中”。


请注意,我可能完全误解了您的问题,很抱歉!:)


人类而学习(也就是说,通常学习如何建模)不应像瀑布一样走,而应该为模型学习。否则,测试数据的某些部分将潜入训练数据中,并且您的模型更容易过度拟合。
Michael McGowan

我从软件方面开始更多地考虑它。用户建立了一个模型,该模型在训练中的准确度为90%,在测试中的准确度为75%。然后他们调整软件中的一些旋钮和设置,并在“测试”上获得80%的准确性。他们再次返回并进行更多调整,并在“测试”上获得85%的准确性。但是,这个所谓的“测试”数据集不再超出样本范围,并且该模型已经过拟合。
Michael McGowan

究竟。这是一个人类学习的问题(如果可能的话,是老师的问题)。应该尽快揭示它,而不是通过“确保X不会泄漏到Y”的人为手段将其隐藏起来
andreister 2012年

应该更了解的人仍然会犯这个错误。您可以在软件包中通过某种工作流程来在某种程度上减轻这种影响,该工作流程可隐式或显式地鼓励良好做法并鼓励不良做法。人类应该更好地了解是没有理由忽略这个问题的。
Michael McGowan

@MichaelMcGowan-您也忽略了泄漏的好处-通过使用测试集,您的算法可能得到了改进(即,训练+测试比仅训练更多的数据)。实际上,这只是权衡取舍,提高了精度,而改进了精度测量。对于我来说,前者更为重要。
概率
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.