sklearn train_test_split按受试者(参与者)进行纵向(面板)研究



我有一个随时间观察的多个主题的数据集。我将在其上训练一个序列模型,并且我需要按主题(研究参与者)将其分成训练/测试。

我提供了我当前的解决方案作为答案。


示例数据集:

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'])

然后像以前一样继续。

如果您想通过连续列进行分层,请查看本文。

相关内容

  • 没有找到相关文章

最新更新