我正在参加一项数据科学竞赛,我的测试集的分布与训练集的分布不同。我想从与测试集非常相似的训练集中对观察结果进行子采样。
我怎样才能做到这一点?
我正在参加一项数据科学竞赛,我的测试集的分布与训练集的分布不同。我想从与测试集非常相似的训练集中对观察结果进行子采样。
我怎样才能做到这一点?
很好的问题,这就是机器学习范式中所谓的“协变量偏移”、“模型漂移”或“非平稳性”等等。
建立机器学习模型以进行未来预测的关键假设之一是看不见的数据(测试)来自与训练数据相同的分布!然而,实际上,这个相当简单的假设很容易被打破,即将到来的数据(其分布)由于多种原因而随着时间的推移而变化。对于那些可能不熟悉这个非常重要的问题的人,我鼓励在这里查看或发帖!
对我来说,你的问题属于同一类。虽然我没有完美的解决方案(提供一个实现),但我想你可能会看:
快速更新(一个很好的解决方案):我找到了该研究论文(最后一点)的 KLIEP 算法的 Python 实现来找到这些权重。它似乎很容易使用!基本上,它通过放置权重(通过 KLIEP 算法)对训练进行重新采样,以使训练和测试分布相似的假设尽可能地成立。
我想从与测试集非常相似的训练集中对观察结果进行子采样。
我不确定你是否愿意这样做。整个目的是训练您的算法,以便它可以很好地推广到看不见的数据。
通常,应该将其测试数据调整到其训练数据(例如,根据训练数据标准化测试数据),而不是相反。在实践中,您不知道您的测试数据。
训练集子采样可能不是最好的解决方案!
测试/执行集和训练集分布/特征之间的差异在监督学习任务中非常常见(这也是 Kaggle 等竞赛具有挑战性的原因之一)。这就是为什么我们说过去的表现可能(仅)用作估计未来表现的指南,但它并不表明/保证它。因此,可泛化模型总是比微调模型更受欢迎,微调模型可能在训练(子)集上表现非常好,但在看不见的数据上表现不佳。
虽然这种差异是正常的,但过去和未来样本之间的太大差距可能被称为概念漂移的例子,这本身就是一个活跃的研究领域。鉴于您的问题,我无法判断您的案例是正常的 ML 案例,还是确实发生了概念漂移。
这些是我的建议:
训练多个具有高泛化能力的模型。使用训练数据集中的引导抽样,您可以轻松计算误差的偏差和方差分量。回想一下,您正在寻找低方差模型(其中数据的变化对其性能有边际影响),而不是低偏差但高方差的模型(可能会过度拟合您的训练(子)集)。现在,您可以选择最佳算法并根据测试集对其进行评估。请注意,在训练时我们不应该查看测试集!
寻找标准化/归一化和特征选择/工程,而不是几个随机下采样。这些技术在学习更通用的模型时可能是实用的。例如,有时特征域的范围可能会随着时间而改变,而分布的形状(无论它是什么)几乎保持不变(例如向左或向右移动的相同分布)。在这种情况下,简单的标准化(即使用不同的映射函数将训练和测试样本映射到预定义的空间,例如 [0,1])可以减轻症状。
如果您基于对问题的一些了解(不仅仅是为了在测试数据集上获得更好的准确性)进行系统下采样,那么它只能是一个合适的解决方案。例如,您可能知道火车数据中的某些记录是很久以前从远场采样的,或者受到将来不会发生的特定因素的影响(在测试数据收集中)。在这种情况下,您可以删除那些可能不相关的样本,因为您确信将来不会看到此类模式(我的意思是,您应该在选择训练子集的背后有一个基本原理,而不是查看测试集实际上,您无权访问它)。在这种情况下,我称之为异常值去除 而不是下采样。
python中有一个很好的包(scikit learn)
http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
您可以使用此包从训练集中对您的观察进行二次抽样。