0


如何选择数据拆分方法:不同数据拆分方法的优缺点及原因

拆分可用的数据是有效训练和评估模型的一项重要任务。在这里,我将讨论 scikit-learn 中的不同数据拆分技术、选择特定方法以及一些常见陷阱。

本文包含易于使用的代码块,并提供快速总结以供参考。随意将本文加入书签以备后用。

在第一次学习数据科学时,拆分数据是一项主要任务。

为什么应该只使用部分数据?是否有更多数据供我的模型学习以产生更好的结果?

虽然人们一致认为在构建预测模型时更多的数据会产生更好的模型,但重要的是要考虑如何使用模型。

在将模型发布到世界各地之前,在开发过程中测试模型是必不可少的。尽管如此,必须仅使用可用数据,这意味着将一些数据放在一边作为的现实生活”数据。

但调查实际“现实生活”数据至关重要。这个问题的答案决定了应该如何分离你的数据。

train_test_split

在最简化的数据分离形式中,随机抽取一部分数据,将其放在一边供以后测试。很简单,但停下来想想正在做的假设。

此方法假设数据来自相同的分布。例如,假设您的数据每年都在变化。假设您对最近一年的大部分数据进行了采样(甚至可能是由于随机选择而偶然发生的)。在这种情况下,您的模型可能无法有效处理今年的预测。

有足够的数据使你的数据集具有代表性。如果拥有来自相同分布的数据但只有 100 个实例,则选择包含 10% 数据的测试集可能会提供偏斜的结果。如果这 10 个数据点来自数据中最异常的区域,则模型性能会更差。当您有更多数据实例时,这种情况不太可能发生。

对于分类问题,是否需要考虑每个类的部分?假设您有一个高度偏斜的分类问题(根据我的经验,通常是这种情况)。在这种情况下,可能需要考虑对数据集进行分层。这一点几乎落入了前一点,测试集可能太小,但在这种情况下,对于您尝试预测的某个类来说,它太小了。

如果您想执行内部交叉验证,这种拆分方法是完美的。将数据拆分为训练和测试,并在训练模型时应用交叉验证方法。如果来自同一分布的足够数据,此方法有效

在中大型数据集上使用 train_test_split,数据来自相同的分布

import numpy as np
from sklearn.model_selection import train_test_split

# Update with your data
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([1, 2, 3, 4, 5])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=10)

train_test_split拆分的一个缺点是,当您进行拆分时,会决定测试集中的数据将始终是您的测试数据。

这有一些缺点。

在训练时,您永远不会在模型中包含测试数据。您的测试数据中可能存在会使您的模型更加健壮的实例。

测试数据是固定的。最后,这个测试集存在过度拟合的微妙问题。虽然这不像过度训练神经网络以完美地学习数据那样明确,但这种类型的过度拟合仍然是一个问题。修复此数据后,您执行的实验将针对此测试集进行重复测试。您将搜索在该集合上表现最佳的模型。但是考虑一下预测建模的原始问题。你不知道未来的数据会是什么。通过针对固定测试集反复测试,您正在做一些在现场场景中不可能完成的事情。

kFold

作为训练-测试拆分的替代方案,K-fold 提供了一种机制,可将数据集中的所有数据点用作训练数据和测试数据。

Kfolds 将数据集分成多组零重叠的索引,以从您的数据集中提取随机数据集。

这种方法优于之前的train_test_split,因为每个数据点都可以是模型和测试集的一部分。然而,这意味着一些事情。

您将在每个训练数据集上构建多个模型并在每个测试数据集上进行测试。虽然这对于小数据集来说很好,但是当模型很大并且数据集很大时,事情很快就会变得昂贵。

测试之间的性能不同。这种性能上的变化是一件好事。您可以计算有关您的表现的统计数据(即,您可以从多次评估中获得标准偏差和平均值)。您还可以更深入地了解模型在不同场景中的表现。

通常,在使用这种类型的数据分割时,每次测试的平均值对模型在实时环境中的表现给出了更可靠的解释。外部交叉验证以这种方式创建多个模型,报告所有折叠的平均性能,然后根据所有数据制作最后一个模型。这个最终模型受益于使用所有数据。但是,除非有其他数据,否则无法对其进行测试。因此,在这种情况下,模型性能的平均值被用作该模型的性能。

当您的数据来自同一分布时,将 KFold 用于中小型数据集

import numpy as np
from sklearn.model_selection import KFold

# Update with your data
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([1, 2, 3, 4, 5])

KF = KFold(n_splits=5)
for train_index, test_index in KF.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

时间序列拆分

前面两种方法都认为你拥有的数据是可以随机抽样的。但是,在时间序列数据中,您不能随机采样数据。最重要的原因是,没有现实生活场景可以让您用未来的数据训练模型来预测过去。

相反,您可以按时间分离数据。例如,获取数据点之前的所有数据,然后在下一个数据点上对其进行测试,以确保不会出现数据泄漏。从这个意义上说,泄漏将使用未来的数据来预测以前的数据。

这种拆分方法是三者中唯一考虑随时间变化的分布的方法。因此,当您拥有随时间变化的数据时,可以使用它。

对时间序列数据或数据分布随时间变化时使用 TimeSeriesSplit。

import numpy as np
from sklearn.model_selection import TimeSeriesSplit

# Update with your data
X = np.array([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
y = np.array([1, 2, 3, 4, 5])

time_series_cv = TimeSeriesSplit(gap=0, max_train_size=None, n_splits=5, test_size=None)for train_index, test_index in time_series_cv.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

总结

构造模型很有趣。但是,尝试提高模型的性能可能是一项无止境的任务。虽然您可能在一组数据上具有出色的性能,但考虑如何在现实世界中使用您的模型至关重要。不同的拆分方法有不同的用途,因此请相应地选择。

记住要专注于目标问题,而不仅仅是某些测试集上的最高性能。

本文作者:Zachary Warnes

标签:

“如何选择数据拆分方法:不同数据拆分方法的优缺点及原因”的评论:

还没有评论