使用Numpy分层将数据分为训练,测试和验证

时间:2019-01-27 19:31:13

标签: python python-3.x pandas numpy pandas-groupby

我刚刚看过这个answer on SO,它显示了如何使用numpy分割数据。

假设我们要分别将它们分为0.80.10.1进行培训,测试和验证,请按照以下方式进行操作:

train, test, val = np.split(df, [int(.8 * len(df)), int(.9 * len(df))])

我想知道在使用这种方法拆分数据时如何考虑分层。

  

分层是在拆分数据的同时保留数据中每个类别的先验知识。就是说,如果您要参加0.8的培训,则从每个课程中获得0.8 。测试和训练也一样。

我尝试首先使用以下类对数据进行分组:

grouped_df = df.groupby(class_col_name, group_keys=False)

但是它没有显示正确的结果。


注意:我熟悉train_test_split

2 个答案:

答案 0 :(得分:1)

这假设您已经进行了分层,因此“类别”列指示每个条目所属的分层。

from collections import namedtuple

Dataset = namedtuple('Dataset', 'train test val')

grouped = df.groupby('headline')
splitted = {x: grouped.get_group(x).sample(frac=1) for x in grouped.groups}
datasets = {k:Dataset(*np.split(df, [int(.8 * len(df)), int(.9 * len(df))])) for k, df in splitted.items()}

这将按df中分配的类别名称存储每个分层的分组。

数据集中的每个项目都是一个Dataset命名元组,以便可以分别通过.train.test.val访问训练,测试和验证子集。

答案 1 :(得分:1)

只需使用groupby对象 grouped_df ,该对象由每个子集的数据帧组成,然后可以在其中运行所需的np.split。然后将所有采样的数据帧与pd.concat连接。总之,这将根据您引用的消息进行分层

train_list = []; test_list = [], val_list = []
grouped_df = df.groupby(class_col_name)

# ITERATE THROUGH EACH SUBSET DF
for i, g in grouped_df:
    # STRATIFY THE g (CLASS) DATA FRAME
    train, test, val = np.split(g, [int(.8 * len(g)), int(.9 * len(g))])

    train_list.append(train); test_list.append(test); val_list.append(val)

final_train = pd.concat(train_list)
final_test = pd.concat(test_list)
final_val = pd.concat(val_list)

或者,是使用列表推导的简写:

# LIST OF ARRAYS
arr_list = [np.split(g, [int(.8 * len(g)), int(.9 * len(g))]) for i, g in grouped_df]

final_train = pd.concat([t[0] for t in arr_list])
final_test = pd.concat([t[1] for t in arr_list])
final_val = pd.concat([v[2] for v in arr_list])