我有一个随时间观察的多个主题的数据集。我将在其上训练一个序列模型,并且我需要按主题(研究参与者)将其分成训练/测试。
我提供了我当前的解决方案作为答案。
示例数据集:
from pydataset import data
longitudinal_study = data('Blackmoor')
longitudinal_study.head(10)
subject age exercise group
1 100 8.00 2.71 patient
2 100 10.00 1.94 patient
3 100 12.00 2.36 patient
4 100 14.00 1.54 patient
5 100 15.92 8.63 patient
6 101 8.00 0.14 patient
7 101 10.00 0.14 patient
8 101 12.00 0.00 patient
9 101 14.00 0.00 patient
10 101 16.67 5.08 patient
预期输出:
# Not Implemented
# train_df, test_df = train_test_split(longitudinal_study, by='subject', test_size=0.1)
assert len(set(train_df.subject).intersection(set(test_df.subject)))==0
我有三个问题:
- 如何解释
test_size
?如果不同参与者的观察次数不同怎么办? - 如何根据其他属性进行分层?
- 主要问题:拆分纵向数据的最佳方式是什么?
scikit-learn
或其他库中有哪些可用的工具?
可以对列subject
的唯一值使用标准的train_test_split
。
import pandas as pd
from sklearn.model_selection import train_test_split
subjects = longitudinal_study.subject.unique()
subjects_train, subjects_test = train_test_split(subjects, test_size=0.1)
train_df = longitudinal_study[longitudinal_study.subject.isin(subjects_train)]
test_df = longitudinal_study[longitudinal_study.subject.isin(subjects_test)]
我想补充你的解决方案,与其保留一组唯一的subjects
,不如保留每个subject
的最后观察结果,并根据你的目标(甚至是一个功能)分层。
两种解决方案将产生本质上相同的结果,但是如果您的数据随着时间的推移变得不平衡,那么根据每个subject
的最后观察周期进行分层可能很重要。
# Keep last row of each subject
subjects = df.groupby('subject').last().reset_index()
# Split this data stratifying by `group`
subjects_train, subjects_test = train_test_split(subjects['subject'], train_size=0.9, test_size=0.1, stratify=subjects['group'])
然后像以前一样继续。
如果您想通过连续列进行分层,请查看本文。