在开发预测模型时,数据泄露是机器学习中的一个大问题。
数据泄露是指在创建模型时使用了训练数据集以外的信息。
在这篇文章中,您将了解预测建模中数据泄露的问题。
阅读本文后,您将了解
- 什么是预测建模中的数据泄露。
- 数据泄露的迹象以及为什么它是一个问题。
- 您可以用来最小化预测建模问题中数据泄露的技巧和窍门。
通过我的新书《机器学习数据准备》**启动您的项目**,其中包括**分步教程**和所有示例的**Python源代码**文件。
让我们开始吧。

机器学习中的数据泄露
照片作者:DaveBleasdale,保留部分权利。
预测建模的目标
预测建模的目标是开发一个模型,该模型能够对训练期间未见过的新数据进行准确预测。
这是一个难题。
之所以困难,是因为我们无法评估我们没有的东西上的模型。
因此,我们必须通过仅使用部分现有数据进行训练,并使用其余数据进行评估来估计模型在未见数据上的性能。
这是交叉验证以及旨在减少此估计中方差的更复杂技术所依据的原则。
想开始学习数据准备吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
什么是机器学习中的数据泄露?
数据泄露可能导致您创建过于乐观,甚至完全无效的预测模型。
数据泄露是指在创建模型时使用了训练数据集之外的信息。这些额外的信息可以让模型学习或了解它原本不会知道的东西,从而使正在构建的模型的估计性能失效。
任何其他特征,如果其值在您想要使用模型进行预测时实际上在实践中不可用,那么该特征就可能给您的模型引入泄露。
当你用来训练机器学习算法的数据碰巧包含了你试图预测的信息时
— Daniel Gutierrez, Ask a Data Scientist: Data Leakage
计算机安全中有一个叫做数据泄露和数据丢失预防的话题,它与我们正在讨论的有关,但并非同一个概念。
数据泄露是一个问题
这至少有3个原因,这是一个严重的问题
- **如果您正在进行机器学习竞赛,这是一个问题**。顶尖模型将使用泄露的数据,而不是作为底层问题的一个好的通用模型。
- **当您是提供数据的公司时,这是一个问题**。逆转匿名化和混淆可能会导致您意想不到的隐私泄露。
- **当您正在开发自己的预测模型时,这是一个问题**。您可能正在创建过于乐观的模型,这些模型实际上毫无用处,无法投入生产。
作为机器学习从业者,我们主要关注最后一种情况。
我有数据泄露吗?
判断您是否存在数据泄露的一个简单方法是,如果您取得的性能好得令人难以置信。
就像你能预测彩票号码或高精度地选股一样。
“好得令人难以置信”的性能是其存在的“一个明显的迹象”
— 第13章, 《数据科学实战:来自前线的真知灼见》
数据泄露通常是复杂数据集的更大问题,例如:
- 时间序列数据集在创建训练集和测试集时可能很困难。
- 图问题中随机抽样方法可能难以构建。
- 模拟观测值,如声音和图像,其中样本存储在具有大小和时间戳的单独文件中。
构建模型时最小化数据泄露的技术
在开发预测模型时,您可以使用以下两种很好的技术来最小化数据泄露:
- 在交叉验证折叠内执行数据准备。
- 保留一个验证数据集,用于对您开发的模型进行最终的健全性检查。
通常,最好同时使用这两种技术。
1. 在交叉验证折叠内执行数据准备
在为机器学习准备数据时,很容易泄露信息。
其影响是训练数据过拟合,并且对模型在未见数据上的性能评估过于乐观。
例如,如果您对整个数据集进行归一化或标准化,然后使用交叉验证来估计模型的性能,那么您就已经犯了数据泄露的错误。
您执行的数据重缩放过程在计算缩放因子(如最小值和最大值或均值和标准差)时,对训练数据集中数据的完整分布有所了解。这种知识被印刻在重缩放的值中,并被交叉验证测试工具中的所有算法利用。
在这种情况下,对机器学习算法进行无泄露评估的方法是:在交叉验证的每个折叠内计算数据重缩放参数,并在每个循环中使用这些参数准备保留的测试折叠上的数据。
作为数据科学家,现实情况是,任何时候您准备、清理数据、填充缺失值、去除异常值等,您都有可能制造数据泄露的情况。您可能会在准备数据的过程中扭曲数据,以至于您构建的模型在您的“干净”数据集上表现良好,但在您实际希望应用的真实世界场景中却完全失败。
— 第313页, 《数据科学实战:来自前线的真知灼见》
更普遍地说,无泄露的数据准备必须在交叉验证周期的每个折叠内进行。
对于某些问题,您可能可以放宽此限制,例如,如果您可以自信地估计数据的分布,因为您拥有其他领域知识。
然而,总的来说,一个好主意是在您的交叉验证折叠中重新准备或重新计算任何所需的数据准备,包括特征选择、异常值移除、编码、特征缩放和用于降维的投影方法等等任务。
如果您对所有数据执行特征选择,然后进行交叉验证,那么交叉验证过程的每个折叠中的测试数据也被用于选择特征,这会偏倚性能分析。
— Dikran Marsupial,在回答Cross Validated上提出的“特征选择与交叉验证”问题时如是说。
R 和 Python 中的 scikit-learn 等平台通过 R 中的 caret 包和 scikit-learn 中的 Pipelines 帮助自动化这一良好实践。
2. 保留验证数据集
另一种,也许更简单的方法是将您的训练数据集分成训练集和验证集,并存储验证数据集。
一旦您完成了建模过程并实际创建了最终模型,请在验证数据集上评估它。
这可以为您提供一个健全性检查,以查看您的性能估计是否过于乐观并存在泄露。
从本质上讲,真正解决这个问题的唯一方法是保留一个独立的测试集,并在研究完成之前一直将其保留,用于最终验证。
— Dikran Marsupial 在回答 Cross Validated 上提出的“如何帮助确保测试数据不会泄露到训练数据中?”问题时如是说。
5个应对数据泄露的技巧
- **时间截断**。删除所有在感兴趣事件发生之前的数据,重点关注您了解到事实或观察的时间,而不是观察发生的时间。
- **添加噪声**。向输入数据添加随机噪声,以尝试平滑可能泄露变量的影响。
- **移除泄露变量**。使用账号和ID等变量评估简单的基于规则的模型(如OneR),以查看这些变量是否泄露,如果是,则将其移除。如果您怀疑某个变量存在泄露,请考虑将其移除。
- **使用管道(Pipelines)**。大量使用管道架构,它允许在交叉验证折叠中执行一系列数据准备步骤,例如R中的caret包和scikit-learn中的Pipelines。
- **使用保留数据集**。保留一个未见的验证数据集,作为模型最终使用前的健全性检查。
关于数据泄露的进一步阅读
关于数据泄露的资料不多,但那些珍贵的论文和博客文章都是金子般的。
以下是一些您可以用来了解更多关于应用机器学习中数据泄露的更好资源。
- 数据挖掘中的泄露:公式化、检测与规避 [pdf], 2011. (推荐!)
- 数据怀疑论者播客中的数据泄露迷你剧集.
- 第13章:从数据竞赛中学到的经验教训:数据泄露和模型评估,摘自《数据科学实战:来自前线的真知灼见》,2013年。
- 请教数据科学家:数据泄露, 2014
- Kaggle Wiki上的数据泄露
- ICML 2013年鲸鱼挑战赛中关于数据泄露的精彩讨论
总结
在这篇文章中,您了解了在开发预测模型时机器学习中的数据泄露问题。
您学到了
- 在开发预测模型时,什么是数据泄露。
- 数据泄露为何成为问题以及如何检测它。
- 在开发预测模型时,您可以用来克服数据泄露的技术。
您对数据泄露或这篇文章有什么疑问吗?请在评论中提问,我将尽力回答。
所以,如果我把60%的数据用于训练,另外40%留作测试,然后在分割后对两者进行缩放,我就能避免数据泄露,对吗?
嗨,Calvin,最佳实践是从训练数据集中学习如何缩放,然后利用这些知识来缩放测试数据集。
感谢您的本教程,但我有一个问题
如果我手动清理训练集,我如何对测试集做同样的事情呢?
请问是否有可能看到一个教程,我们学习如何清理训练集,例如使用 clean = missForest()
X_trainf = clean.fit_transform(X_train)
X_testf = clean.transform(X_test)
好问题。
在训练集上准备转换,然后将其应用于训练集和测试集。
你好,Jason
很棒的文章。
通常,在我完成所有数据处理、特征创建、PCA、异常值移除、二进制编码后,我会将数据分成3个集合(85%训练,10%验证,5%测试)。
然后我在训练集上进行所有交叉验证、网格/随机搜索等,可能会对特征进行一些调整(例如添加前2/3个预测变量的交互项或幂次项),并在验证集上验证结果。这通过不同的建模技术完成。
一旦我找到了最佳模型,我只会**一次**在测试集上评估它的性能。
几个问题。
1. 我没怎么见过这样做,但是否有人会把训练集的填充值存储起来,然后用这些值来填充未知的测试集?例如,未知的测试集可能是在Kaggle竞赛中用来评估模型性能的那个。
当我使用一些R包来填充数据(例如 amelia 等)时,这些包使用了比普通均值/众数/中位数更复杂的填充方法,这会如何运作?
是否也应该在未知集上运行该包?
在构建的模型中,当我用训练数据填充未知测试集与用它自己的均值/中位数等填充未知集时,结果并没有太大差异。
2. 类似于填充,您对异常值方法有什么建议?也许使用了一些单变量或多变量方法来检测训练数据集中的异常值,然后(比如说)用均值/中位数等替换了异常值。
如何执行相同的步骤并减轻对未知测试集的泄露?
3. 是否有可能看到一个关于如何在每个交叉验证折叠中执行异常值移除、编码、特征缩放、填充的示例?
我知道 caret 允许在训练模型时执行 PCA(但那样我怎么知道它选择了多少个主成分),或者最近使用 H2O,不建议创建二进制特征,因为 H2O 会自动处理。
谢谢 Sandeep。
不错的做法,尽管我建议根据问题的具体情况更改百分比。
任何用于转换训练数据的模型(如填充)都必须存储起来,以便将来用于任何新数据,如测试集和验证集,甚至是新数据。它现在是模型的一部分。
异常值很棘手。像上面一样存储异常值模型。您通常希望在模型构建后以相同的方式过滤数据,并可能对超出训练数据集范围的数据返回“我不知道”的预测。我在这里稍微谈了一下异常值。
https://machinelearning.org.cn/how-to-identify-outliers-in-your-data/
我没有一个关于异常值移除的例子,我想。抱歉。
好信息!
但我感到困惑。
在那篇文章中,Dikran Marsupial,在回答“特征选择和交叉验证”问题时,这里的特征选择是指变量选择吗?
而且,数据泄露在R工具中不是问题。因为有函数可以解决这个问题。(在train()函数中,我们可以使用“CV”方法或“repeatedCV”)这是对的吗???
谢谢!
如果我们在拟合模型时使用测试集中的信息,那么数据泄露在R或任何平台中都可能是一个问题。
这可以像在缩放训练数据时包含测试数据一样简单。
你说得对,像 caret 这样的工具大大降低了这种风险,如果这些工具使用得当(例如,缩放是在每个交叉验证折叠内进行的)。
如果我们把数据分成5折,然后,先对前4折进行缩放,预测第5折。之后,我们使用另外4折并对其进行缩放。那么第一折(已经和前一组一起缩放过)怎么办?我们怎么取消缩放?另外,测试折也需要缩放吗?
是的,执行的任何转换都会被丢弃或反转。
您的网站真的很有帮助,尽管我仍然有点模糊,为什么在学习之前对整个训练数据集(可能是所有数据的70%)进行归一化或标准化会导致泄露。为什么了解大部分数据的分布会导致问题呢?
为了缩放数据,您需要系数(最小值/最大值或平均值/标准差)。
这些必须最好从数据中估计(除非您从领域中知道确切的值)。
如果它们是从整个数据集估计的,那么就会发生泄露,因为使用了测试集中的知识来缩放训练集。
首先,Jason,感谢您出色的博客!
回到问题,那您有什么建议?在分割(train_test_split)数据集后执行归一化(min/max)吗?
谢谢您。
是的,分割后,从训练数据中获取系数,然后应用于训练集、测试集、其他...
你好!例如,如果我在NaNs填充中使用训练集的均值。这个均值必须是应用于测试集的参数,还是我需要重新计算测试集中的均值?
例如。
训练集
10
Nan
5
10
5
Nan – >5(均值)
测试集
1
1
2
Nan
2
Nan – >来自训练集的10还是测试集的1.5(均值)???
均值将仅从训练数据集中估计。
关于机器学习的优秀博客,信息详细。感谢您的努力,Jason。
谢谢。
感谢您创建了如此非常有用的博客,我发现我经常回来查阅!1)通过目标编码目标变量的均值,按X特征分组,并在折叠外交叉验证集中测量,来工程特征的一般方法是什么?我以前见过这是一个重要的工程特征。2)这是否非常容易导致数据泄露?如果是,为什么?
再次感谢您!
只要均值或其他统计数据仅基于训练数据,就不会发生泄露。
嗨,Jason,
什么是验证数据集,我如何准备它以保留下来进行模型健全性检查,正在构建的模型?
我是否需要进一步分解训练集来制作验证数据集?如果我错了,请纠正我。
这篇文章将解释验证数据集
https://machinelearning.org.cn/difference-test-validation-datasets/
你好,
所以我的理解是,数据预处理应该在交叉验证的每个折叠中完成。我们可以通过caret包来完成。caret也能处理每个折叠中的多重共线性吗?
谢谢。
是的,数据准备必须为每个折叠执行。
Caret 可能支持多重共线性,我手头不确定。
你好,
那么,如果在交叉验证期间对每个折叠进行数据预处理,例如Box-Cox变换、中心化,我们就不需要在初始阶段(例如探索性数据分析期间)进行相同的预处理了吗?
我之所以问这个问题,是因为我大多数时候看到人们在探索性数据分析期间进行数据预处理(例如缺失值填充、异常值移除)。只是想有个清晰明了的概念!!
谢谢
理想情况下,我们应该在CV折叠内进行此操作,以避免泄露。有时,它对结果的影响不大。
你好,
当我们添加新属性、删除属性或在拟合模型之前创建虚拟变量时,这些操作也会导致数据泄露吗?
如果该过程使用了数据样本之外的信息,则可能发生。
嗨 Jason,确实是一篇很酷的文章。
我无法理解这句话在数据泄露语境中的含义:“如果任何其他特征的值在您想要使用模型进行预测时实际上在实践中不可用,那么该特征就可能给您的模型引入泄露。”
从上面我理解的是,我们有一个特征,其值在生产阶段无法计算。如果是这样,这意味着我们在特征选择步骤中犯了一个错误。要解决它,我们需要删除该特征并重新训练我们的模型。这个错误是否与数据泄露有关?
如果您能给我一个具体的例子,那将非常有帮助 😉
谢谢
这意味着如果你使用了你没有的数据信息,例如未来数据或样本外数据,那么你就存在数据泄露。
这有帮助吗?
我觉得我在理解它的正确轨道上 🙂
坚持住!
关于未来数据示例,如果您拥有的数据包含预测不需要的数据,请不要使用它。例如,如果预测问题是预测疾病的发生,并且数据还包括已施行的治疗列(未来数据),这可能是由于未来数据引起的数据泄露的示例。因此,了解与领域专家主题的决策流程有助于 формуulate 问题。
好建议!
“数据挖掘中的泄露:公式化、检测与规避 [pdf], 2011. (推荐!)” 的链接 http://dstillery.com/wp-content/uploads/2014/05/Leakage-in-Data-Mining-Formulation-Detection-and-Avoidance.pdf 已失效。
谷歌搜索标题后发现:
https://www.cs.umb.edu/~ding/history/470_670_fall_2011/papers/cs670_Tran_PreferredPaper_LeakingInDataMining.pdf
谢谢!那篇文章确实谈到了一些很好的泄露例子。
嗨,Jason,
感谢您免费在线提供这些文章。在今年夏天学习Keras的过程中,它们非常有帮助。
我觉得这篇文章会受益于一些实用的——即使是人为的——泄露例子。我认为它很好地涵盖了理论,但通过实际发生的泄露以及如何修复的例子,才能真正把这个观点讲清楚。
当我在评论中搜索“例子”时,我想我是在重复 Sandeep 和 Tudor 的话。
感谢您的建议。
先生,您能提供数据泄露预测的代码吗?
你到底是什么意思?你有什么例子吗?
感谢您的精彩网站和文章。我对其中一部分有点困惑:如果特征选择发生在折叠中,那么最终选择的模型是什么?我曾认为重复的k折叠例如会平均化模型,以给出最终的准确率。(例如,重复的k折叠会给出关于预测准确率不确定性的一些概念)。
但是如果每个折叠使用的特征都不同,那么建议的最终特征集是什么?
谢谢!
好问题,我们用所有可用数据训练一个最终模型。
这篇文章详细解释了这一点
https://machinelearning.org.cn/train-final-machine-learning-model/
如果我理解正确,Milley 正在问,如果对每个折叠应用特征选择,那么每个折叠中可能会有一组不同的特征。那么你如何
你是否根据性能最好的折叠中选择的特征来选择最终的特征集?
我没有在链接的文章中看到任何关于特征选择的提及。
请继续努力! 🙂
我明白了,好问题。
没有最好的方法。一种方法是使用所有折叠中选择的顶级特征的平均值或超集。
或者,在训练之前使用保留验证集。
提问者在这里提出的观点需要更多的回应。如果你在交叉验证折叠中进行特征选择,那么你在交叉验证执行中最终测试的是一个模型构建过程,而不是一个模型(尽管有些人实际上将其包含在他们的“模型”概念中)。但大多数人在预测中寻求的是模型的性能,而不是整个模型构建过程的性能。因此,虽然这种方法可以避免数据泄露问题,但它无法满足大多数人在预测中的需求,这意味着它不适合解决它本应解决的需求。
换句话说,当这些人问“最终模型是什么?”时,他们问这个问题是因为这种交叉验证方法没有选择模型,而是选择了一个构建模型的过程。如果你想知道某个特定模型(而不是模型构建过程)在未知/未来数据上的表现,那么你必须预选特征并在每个模型折叠中以类似的方式测试它们。可以创建一个保留集,该保留集未用于特征选择过程,也未用于交叉验证执行。
我会争辩说你不能(也不应该)将两者分离。只有模型构建过程(数据准备+模型),例如原始数据输入,预测输出。
最终模型是将模型选择应用于(数据准备+模型)的结果,更多信息请看这里
https://machinelearning.org.cn/train-final-machine-learning-model/
这有帮助吗,Paul?
也许我们只是在“在交叉验证折叠中进行特征选择作为模型选择过程的一部分”这个场景上存在误解。(我的措辞,不是你的。)假设,例如,你计划在你的过程中使用单一算法,即逻辑回归。为了选择特征,你决定也只使用一个特定过程:选择在对结果进行单变量回归时,相关p值小于0.05的所有特征。因此,这在10个交叉验证折叠中的每个折叠都是过程的一部分。现在,完成交叉验证后我们得到了什么?我们可能有10个逻辑回归模型,所有模型都具有不同的特征(每个折叠一个)。其他评论者问的问题是,“这如何告诉我们用于未来数据预测的模型?”我认为他们指的是“我选择这些逻辑回归模型中的哪一个?”我认为答案是,“它不能告诉你。”它所做的是告诉我们,如果我们使用所述过程(逻辑回归,特征选择基于单变量p值小于0.05)并使用我们当前的训练数据集来构建模型(尽管交叉验证的变异性可能稍微高估了变异性),我们应该期望在未来数据上看到平均预测误差。所以它没有告诉我们使用哪些特征,它告诉我们如果我们使用该特征选择过程来选择作为逻辑回归算法输入的特征会发生什么。也就是说,它只是间接告诉我们使用哪些特征(使用p值小于0.05的过程)。
然而,他们(和大多数人)可能正在考虑从一组选择中选择一个模型。为了**选择**一个模型,我们需要在每个折叠中不同的东西(不同的特征选择过程、不同的算法或两者兼有),但这些东西在所有折叠中保持不变。例如:我将比较岭回归(使用所有可用特征)与逻辑回归(特征选择基于p < 0.05)。现在我有一个交叉验证过程,它给我两件事:一种选择最佳模型构建过程的方法,以及对未来数据上平均误差的估计。
误解(如果有的话)来自于认为你指的是上述第一个场景,而你可能指的是第二个场景。第二个场景告诉你如何从不同的模型中进行选择。第一个场景则不能。但无论哪种情况,我认为这种具体的细节在传达这些信息时都提供了很大的清晰度。
我想我同意。
澄清一下
然而,对“模型”进行单次k折交叉验证评估的结果是模型在对样本外数据进行预测时的性能估计。此过程针对另一个“模型”重复,并比较分数以执行“模型选择”。除了数据之外,我们不会改变折叠中的任何内容。
所有在k折交叉验证期间拟合的模型都会被丢弃。通常情况下。我们可以开发它们的集成模型或其他(例如超级学习器/堆叠),但现在先忽略这一点。
一旦选择了“模型”,我们就用所有数据拟合它,然后开始对来自领域中没有已知输出/目标的新示例进行预测。
你好,谢谢你的好博客
你能解释一下“OneR”和“Cutoff”吗?
时间截断
移除泄露变量:使用账号等变量评估简单的基于规则的模型 OneR
OneR 是单规则算法,例如,它选择数据中的一个分割,导致最低错误。
你好,感谢你的精彩帖子!
我目前正在参加Kaggle的一些比赛。而且,有时,Kaggle中也会讨论这样的问题,
这篇文章帮助我理解了机器学习中的“泄露”是什么。
谢谢!
很高兴它有帮助。
我遇到了一种情况,我怀疑数据泄露发生了,但这听起来并不完全像上述情况
假设我对预测某个事件是否可能在特定时间范围内发生感兴趣,但我没有太多事件发生的例子,因为它相当罕见。因此,我可能会将其设置为一个监督学习问题,其中我为研究中的每个受试者获取多个不同时间段的汇总数值数据,以创建更多关于每个受试者的数据。
当我构建完这些观测值时,假设每个受试者有5个观测值,每个观测值都有其自己根据不同的汇总时间段计算出的数值变量,以及一些不受时间限制的分类变量,因此对于给定的受试者它们是相同的。这将是一个分类问题,每个受试者的所有5个观测值的目标变量将指示未来事件是否在感兴趣的时间范围内发生(每个受试者的所有5个观测值在目标变量上具有相同的值)。
现在我想将这些数据分成训练集和测试集。我只是随机打乱我所有的观测值,这样对于我的测试集中出现的任何观测值,很可能有一个或多个来自同一受试者的观测值。如果这样做,并且来自同一受试者的单独观测值最终出现在训练集和测试集中,这是否是数据泄露的非常明确的案例?
通常,如果在分割之前使用一个以上样本的任何抽象/统计量来准备数据集,那么就会出现某种形式的泄露。
听起来您可能正在重新采样数据,这可能是一种泄露。
嗨,Jason,
当对整个数据集进行分类变量编码时,这也会导致泄露吗?目前,我正在对整个数据集中的所有分类变量进行编码,并将编码器保存到相应的numpy文件中。我曾考虑在生产环境中使用这些编码器,当需要对新样本中的分类变量进行编码时。
诚挚地,
您的十大粉丝之一,
比利
不完全是,只要变量的基数是固定的,并且是通用的“领域知识”。
我正在使用基于树的Boosting算法,如xgboost、lightgbm、catboost等,所以缩放或归一化并不是我的需求。
我的问题集中在这样一个事实:我看到许多机器学习黑客马拉松的参赛者在获得“训练集”和“测试集”后,通常会遵循这样一个想法,即将两者合并形成“所有集”,然后通过对分类特征进行分组并聚合连续特征来工程聚合特征,例如“最小值、最大值、均值、标准差”和“计数”。
然后将这些聚合特征与AllSet合并,之后再次分割为TrainSet和TestSet!
这是数据泄露吗?如果是,比如说黑客马拉松后的模型在现实世界问题中真正实现,其中“聚合特征”按计算保留并仅再次与新数据合并。现在,由于已知训练模型在聚合分布上表现良好,这种泄露将如何错误地影响我未来的预测?
很好的问题!
是的,这是泄露,但它无关紧要,因为领域范围仅限于训练集和测试集——针对竞赛或挑战。
你好 Jason,
谢谢您的回答。
所以如果这不是黑客马拉松而是为了在现实世界中部署模型进行真实的未来预测,并且我进行了训练-测试分割,您会建议只在训练集上进行聚合吗?
我建议仅在训练集上进行数据准备,以便对模型+模型准备过程进行公平评估。
你好,你能解释一下“在交叉验证折叠内进行数据准备”中给出的无泄露数据的解决方案吗?谢谢。
是的,在交叉验证期间,任何所需的拟合/统计量都在每个训练/测试分割的训练集中执行。
这有帮助吗?
亲爱的Jason,感谢您的出色工作,
我谷歌搜索后还是经常来到这里 😉...
我长期以来一直有一个问题是
想象一下我们将数据分成训练集和测试集,我们得到 M = mean(TRAIN) 和 SD = std(TRAIN)。
现在我们做我们想做的事情,例如 z_TRAIN = (TRAIN - M) / SD。
但是,我们这里使用的 mean()/std() 是一个固定的 mean(),它取决于所有的训练数据。
如果我们在缩放/转换数据时使用我们根本不知道的 mean() 值,
——如果我们用第一个训练数据值来做。
训练
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^ ^ –> 我们得到所有数据点的均值()
缩放
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^ ^ –> 在这里用我们不知道的均值缩放值怎么可能是正确的呢?
这难道不是数据泄露吗?
使用滚动平均值不是更有意义吗?
训练
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^——–^ –> 我们得到^—^中所有现有点的均值(TRAIN[1:20])
缩放
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
^——^ –> 从这里开始缩放,进行转换
当然,我们会丢失一些数据,而且会更复杂——但这难道没有意义吗?
如果我们处于一个提供越来越多(新)数据的环境中呢?
在问这个问题的时候我想到,这也许只对时间序列数据是必需的?
对完整训练数据进行缩放/转换(就像R中的caret预处理一样)对于时间序列来说是一种有效的方法吗?
此致 laz
很好的问题!
我们在训练集上准备数据预处理和模型,然后将数据预处理应用于测试集,并在测试集上进行评估。
如果您的数据是时间序列(我认为您指的是这个),那么同样适用。您将有一些历史数据,任何最小值-最大值或均值-标准差都可以从这些数据或领域专家知识中准备。
也许您需要一段时间后更新数据预处理/模型。例如,每周/每月/每年。这很常见,并且解决了概念漂移的问题。
https://machinelearning.org.cn/gentle-introduction-concept-drift-machine-learning/
这有帮助吗?
嗨,Jason,
我不太确定我是否理解您的回答。所以如果我有一个时间序列,单独在训练集上应用缩放意味着使用了来自未来的信息,因此应该避免吗?在这种情况下,基本上应该避免对时间序列进行任何标准化/归一化吗?
谢谢您的澄清!
抱歉。我会说得更清楚些。
从数据中计算出的任何用于缩放数据的系数,都必须仅在训练数据上计算。
嗨,Jason,
感谢这篇优秀的教程。
我有一个关于泄露的问题,那就是……什么时候可以忽略数据泄露?
有没有一种情况是数据泄露是好事?
不。考虑并预防它是很重要的,以便开发可靠的模型性能估计。
嗨,Jason,
如果我减少整个数据中某个特征的基数并使用标签编码器,这不算数据泄露吗?
不完全是,标签编码器不会改变特征的基数。它只对变量进行编码并保持基数。
好的,谢谢,但是如果我减少整个数据集中某个特征的基数,这算数据泄露吗?
如果你使用了训练数据集中没有的信息来改变训练数据集中的数据,那可能会发生。
这个定义可能过于严格。这实际上取决于您的项目/应用程序的具体情况,以及您所使用的信息是否是真正的泄露。
尊敬的Jason博士,
一如既往,一篇出色的文章!我正在处理一组不同大小的图像,我想构建一个图像分类模型。作为构建数据集的预处理步骤之一,我想将所有图像调整为图像集中的平均图像大小。然后,我将定义一个维度等于该平均值的特征向量来存储调整大小后的图像。之后,我将数据集分解为训练集和测试集。我泄露数据了吗?另一个问题是选择前N个特征,然后用这些特征定义一个特征向量。之后,我将数据集分解为训练集和测试集。我泄露数据了吗?这两个问题都与使用实际数据定义特征向量(元数据)的维度有关。我不确定在这种情况下如何操作。谢谢!
谢谢!
可能。也许只根据训练集来选择图像大小。
你好,Jason博士
非常感谢您的精彩教程和耐心回答大家的问题。如果您不介意,在我阅读完所有评论后,我想问您一些问题
假设我有一个未触及的数据集,需要进行一些处理,例如,它有NaN值(插补),有分类变量(独热编码),有连续变量(缩放或离散化)。
您是否同意这个流程?
1. 训练/测试集划分(我们得到“xtrain”,“xtest”)
2. 我们获取“xtrain”中的一个变量,比方说“train_var1”,我们需要对这个特征进行缩放。我们得到用于缩放的参数是:max=10, min=2, mean=5。
2.1 问题:既然我们知道“train_var1”使用的参数,我们是要使用相同的参数(max=10, min=2, mean=5)来缩放“test_var1”,还是会为“test_var1”计算它自己的新参数,比如最终得到max=12, min=1, mean = 8。哪种方法是正确的?我觉得两种方法都有问题,因为在第一种方法中,有些值会超出“train_var1”参数的范围,最终会一团糟。在第二种方法中,比例尺会不同,所以“train_var1”中的“0.2”与“test_var”中的“0.2”不相同,它们代表的数字在不同的比例尺下是不同的。
3. 我们通过仅使用“xtrain”进行迭代插补来处理“train_var2”的NaN值,但结果发现“test_var2”也有NaN值,那么我们会只使用“xtest”数据对这个变量进行迭代插补吗?这可能会导致“xtest”中与“xtrain”中完全相同的观测值(所有其他变量都相同)被插补出完全不同的值。
所以对于所有其他过程,我或多或少都有完全相同的问题。我看到有人问过类似的问题,但我真的没有从中理解。
再次非常感谢您抽出时间回答这些问题,希望您能看看我的问题。
不客气。
你可以使用任何你想要的测试工具。你不需要我的批准或许可。但我不能说一个测试工具比另一个更好——只有你才足够了解你的问题,从而选择如何评估模型。
我建议测试一系列的插补方法,并找出哪种方法最适合你的数据集和模型。
嗨,Jason,
抱歉,我并不是想让您评论我用于插补、缩放或其他方法,我们可以忽略这些,它们只是为了提供一个更完整的例子。更重要的是如何阻止数据从训练集泄漏到测试集,并向您展示当我看到他们说预处理应该在训练和测试数据中分别进行时,我不理解的地方。
这有道理吗?
最好的方法是定义一个包含所有您想要使用的操作的管道。
这将强制所有数据准备和插补仅基于训练数据进行,无论使用何种测试方案,从而避免数据泄漏。
嗨,Jason,
谢谢,您最棒了,我会去研究的!不过我想知道管道是使用我提到的两种方法中的哪一种,还是不同的方法,您对此有什么看法吗?
无论您使用训练/测试分割还是多折交叉验证,管道都将始终仅在训练集上拟合,并应用于训练集和测试集。
嗨,Jason,
当对不平衡数据集执行SMOTE时,我们必须首先填充缺失值,因为SMOTE无法处理缺失值。因此,在执行train_test分割之前,我们正在填充缺失值,因为在执行train_test分割之后,SMOTE就没有意义了。这样就存在数据泄漏。在执行SMOTE时,如何克服这个问题呢?
不,你可以只使用训练集首先进行插补。这并不是数据泄漏。
如果你愿意,可以在管道中完成,例如,插补器,然后是SMOTE,然后是你的模型。
所以,您是说在执行 train_test 分割之后,我们可以创建一个包含插补器、SMOTE 等的管道,将其拟合到训练数据上,然后在测试数据上进行预测吗?
是的。或者使用k折交叉验证。
请确保在训练集和测试集上应用相同的方法
是的。
上面的文章和讨论都很精彩。
我认为,我之所以在理解上面的精彩讨论时感到困惑,部分原因在于“训练集”这个词的歧义,因为它被用于多种方式。
例如,有时讨论的是单一的划分:“训练集”(例如80%)和“测试集”(例如20%)。
有时,k-折交叉验证似乎是上下文:最初的划分产生了一个“训练集”(例如80%)和一个“测试集”(例如20%)。然后,如果我们使用10-折交叉验证,最初的“训练集”进一步划分为“训练集”(9折的10种不同组合)和“验证集”(10个不同的单折)。
所以,为了(希望)减少混淆,我的问题将使用以下术语(遵循Max Kuhn):
假设我最初将一个数据集分成一个“训练集”(80%)和一个“测试集”(20%)。我想使用10折交叉验证。因此,我进一步将“训练集”分成10个相等的部分。我们将任意9个部分组合称为“分析集”,将任何一个留出的部分称为“评估集”。我们还假设我想进行插补、平衡、编码、缩放等操作(具体的预处理对于这个例子并不重要,只需要知道需要某种类型的预处理)。
*****这是我的问题(顺便说一句——我正在使用R):*****
预处理(例如,插补、平衡、缩放)是否发生在每个“分析集”上(即,将9个折叠组合作为一个整体处理),然后将相同的预处理(例如,插补、平衡、缩放)应用于相应的“评估集”(即,留出的折叠)?
所以
* 对“分析集”(折叠1-9的组合数据)进行预处理,并将相同的预处理应用于“评估集”(折叠10的数据)。
* 对“分析集”(折叠1-8,10的组合数据)进行预处理,并将相同的预处理应用于“评估集”(折叠9的数据)。
* 对“分析集”(折叠1-7, 9-10的组合数据)进行预处理,并将相同的预处理应用于“评估集”(折叠8的数据)。
………….
* 对“分析集”(折叠2-10的组合数据)进行预处理,并应用于“评估集”(折叠1的数据)。
谢谢!
是的,我们可以用不同的方式创建训练集。无论如何,为了避免数据泄漏而执行数据准备的方式保持不变。
是的,我认为你所描述的是正确的。
谢谢你,Jason。
你好,
您是否发布过关于数据准备以避免数据泄露的实践文章?如果没有,能否发布一篇?
因为通常,数据准备实践文章会在整个数据集上执行预处理技术,而分割通常是模型训练和测试之前的最后一步。
谢谢你。
是的,很多。任何您使用管道的教程。
你好,
我找到一个不错的实践,链接在此
https://machinelearning.org.cn/data-preparation-without-data-leakage/
谢谢你。
太棒了,是的!
你好,
我一直在寻找如何正确避免数据泄漏的答案,也许您能帮我一下。
我知道在应用归一化等转换时,应该在训练数据上进行 fit_transform,然后在测试数据上进行 transform,但是像探索性数据分析和特征工程等阶段的数据泄漏怎么办?
1) 基于组合数据集(训练+测试)设计特征是否正确?
如果是,那难道不会给我们提供通常我们不会获得的有关测试集的信息,从而导致泄漏吗?
例如,通过使用测试数据集,某些特征之间的相关性比仅分析训练集时更高。
2) 假设我们处理连续数值数据,例如年龄。一种处理方法是通过分箱将其预处理成离散的箱/类别。
再次:我们是在整个数据集上进行分箱,还是分别在训练和测试数据上进行?
如果我们分别进行,那么在后续进行独热编码时可能会出现问题,因为训练数据中会有测试数据中不存在的特征,反之亦然。
3) 对偏斜数据应用 log() 转换呢?它也可以应用于整个数据集吗?
我正处于机器学习之旅的开始阶段,所以这些问题可能很琐碎,但无论如何我都会感谢您的帮助。
这些例子将向您展示具体方法
https://machinelearning.org.cn/data-preparation-without-data-leakage/
可能不会,特征应该基于训练集设计,并且过程应该自动化。
你可以引入更广泛的领域知识,但这可能是一个风险,也可能没问题。你需要自己评估。
对数可以直接应用于训练和测试,不使用系数。如果你使用幂变换,情况就不同了。
感谢您分享知识,总是引用书籍和专家的摘录,非常感谢!
不客气,迦勒!