scikit-learn中的分层训练/验证/测试数据集划分

10

已经有如何在scikit中通过train_test_split实现分层训练/测试拆分的描述(Scikit-Learn中的分层训练/测试拆分),以及如何使用np.split随机进行训练/验证/测试拆分的描述(如何将数据分成三个集合(训练、验证和测试)?)。 但是,如何进行分层的训练/验证/测试拆分呢。

我能想到的最接近进行分层(按类别标签)的训练/验证/测试拆分的方法是如下所示,但我怀疑是否有更好的方法可以在一个函数调用中或以更准确的方式实现:

假设我们想要进行60/20/20的训练/验证/测试拆分,那么我的当前方法是首先进行60/40的分层拆分,然后对这第一个40进行50/50的分层拆分,以最终获得60/20/20的分层拆分。

from sklearn.cross_validation import train_test_split
SEED = 2000
x_train, x_validation_and_test, y_train, y_validation_and_test = train_test_split(x, y, test_size=.4, random_state=SEED)
x_validation, x_test, y_validation, y_test = train_test_split(x_validation_and_test, y_validation_and_test, test_size=.5, random_state=SEED)

如果我的方法正确,或者你有更好的方法,请回复我。

谢谢


这里也有同样的问题,你确认这是正确的做法了吗? - AritzBi
1
@AritzBi 我还没有得到任何人的确认,但似乎运行正常。然而,最终我选择了一种不同的方法,即仅对数据进行分层训练/测试拆分,然后在验证时,在训练集中进行分层k折交叉验证。请查看:http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html#sklearn.model_selection.StratifiedKFold - blu
好的,非常感谢!!! - AritzBi
这正是我所做的!很遗憾,sklearn没有内置的方法来实现这一点。 - Gyan Veda
2个回答

5
解决办法是使用StratifiedShuffleSplit两次,如下所示:
from sklearn.model_selection import StratifiedShuffleSplit

split = StratifiedShuffleSplit(n_splits=1, test_size=0.4, random_state=42)
for train_index, test_valid_index in split.split(df, df.target):
    train_set = df.iloc[train_index]
    test_valid_set = df.iloc[test_valid_index]

split2 = StratifiedShuffleSplit(n_splits=1, test_size=0.5, random_state=42)
for test_index, valid_index in split2.split(test_valid_set, test_valid_set.target):
    test_set = test_valid_set.iloc[test_index]
    valid_set = test_valid_set.iloc[valid_index]

但这并没有回答问题,即:所解释的方法是否是一种好的方式? - Alex Dana

2

没错,这正是我会做的——两次运行 train_test_split()。第一次可以将训练集拆分出来,然后该训练集可能会被进一步划分为不同的折叠或保留集。

事实上,如果您使用了包含内置交叉验证的scikit学习模型进行测试,您甚至可能无需明确再次运行 train_test_split()。如果您使用(非常方便的!)model_selection.cross_val_score函数,也是如此。


有一个问题需要将事物分割两次。例如,想象最糟糕的情况。数据集中有11个样本,全部都属于同一类别。你想要将它们分成训练集和测试集,其中训练集有10个样本,测试集只有1个样本。第一次分割可以成功进行,因为它会产生10:1的比例。但是第二次分割无法进行,因为只有一个样本。最好使用k折交叉验证方法。 - Sandeep Thapa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接