使用两个分层类别进行自定义列车测试



我正在尝试使用NLP技术来预测医生记录时患者的心理状态。我有两个类,后缀(multilabel(和mental_status(binary、Lucid或Delirium(。我正在尝试从符合以下规范的精简列表中构建训练和测试集:

  • 共享的唯一后缀列表
  • 对于每个后缀的每组,LucidDelirium至少有一行

我将用样本权重纠正任何不平衡(我只是试图预测mental_status,但我也需要在后缀上平衡数据(。我只需要后缀和mental_statuses的完整笛卡尔乘积中的每个组合至少有一行。

例如,在下面的数据集中,只有DWM通信后缀才能进入列车测试拆分。

suffix              mental_status
DWN Communication   Lucid
DWN Communication   Delirium
DWN Communication   Lucid
DWN Communication   Delirium
DWN Communication   Lucid
DWN Psychiatry      Lucid
DWN Psychiatry      Delirium
DWN Psychiatry      Delirium
DWN Cardio stuff    Lucid
DWN Cardio stuff    Delirium
DWN Blood .....     Lucid
DWN Blood .....     Lucid
DWN Blood .....     Lucid

对于上面的火车例子,我想要的输出是

DWN Communication   Lucid
DWN Communication   Delirium
DWN Communication   Lucid

并测试

DWN Communication   Lucid
DWN Communication   Delirium

我试过

df.groupby(['suffix','mental_status']).filter(lambda x: len(x) > 1)

但它不能确保每个后缀都有一个Delirium和Lucid。

作为另一个例子,

suf ms
11  blood   delirium
15  blood   delirium
0   blood   lucid
1   blood   lucid
5   blood   lucid
6   blood   lucid
10  blood   lucid
16  blood   lucid
3   psych   delirium
19  psych   delirium
4   psych   lucid
8   psych   lucid
9   psych   lucid
13  psych   lucid
14  psych   lucid
18  psych   lucid
7   stool   delirium
2   stool   lucid
12  stool   lucid
17  stool   lucid

将被拆分为

suf ms
11  blood   delirium
0   blood   lucid
1   blood   lucid
5   blood   lucid
6   blood   lucid
3   psych   delirium
4   psych   lucid
8   psych   lucid
9   psych   lucid
13  psych   lucid

suf ms
15  blood   delirium
10  blood   lucid
16  blood   lucid
19  psych   delirium
14  psych   lucid
18  psych   lucid

编辑:

我想我找到了一个解决方案:

from sklearn.model_selection import train_test_split
def custom_split(df, test_size):
f = lambda ms: (
df[df.mental_status==ms]
.groupby('suffix')
.filter(lambda x:len(x)>=1/min(test_size,1-test_size))
.suffix
)
delirium = f('Delirium')
lucid = f('Lucid')
valid_suffixes = set(delirium).intersection(lucid)
df = df[df.suffix.isin(valid_suffixes)]
df_train, df_test = train_test_split(df,test_size,random_state=9,
stratify=df.mental_status+df.suffix)
return df_train, df_test

使用索引和duplicated(keep=False)怎么样?

test = df[~df.duplicated(keep=False)]
output  = df.drop_duplicates()
output = output[~output.index.isin(test.index)]

如果只执行df.drop_duplicates(inplace=True),它能工作吗?看起来这就是它的全部内容,因为您只需要基于两列组合的唯一值。

使用掩码过滤器:

mask = df["DWN" in df['suffix']]
df = df[mask]
df.dropna(inplace=True)

使用Groupby

data="""index,suf,ms
11,blood,delirium
15,blood,delirium
0,blood,lucid
1,blood,lucid
5,blood,lucid
6,blood,lucid
10,blood,lucid
16,blood,lucid
3,psych,delirium
19,psych,delirium
4,psych,lucid
8,psych,lucid
9,psych,lucid
13,psych,lucid
14,psych,lucid
18,psych,lucid
7,stool,delirium
2,stool,lucid
12,stool,lucid
17,stool,lucid"""
df = pd.read_csv(io.StringIO(data), sep=',')
#print(df)
lst=[]
grouped=df.groupby(['suf','ms'])
for group in grouped.groups:
lst.append(group)

print(lst)

输出:

[('blood', 'delirium'), ('blood', 'lucid'), ('psych', 'delirium'), ('psych', 'lucid'), ('stool', 'delirium'), ('stool', 'lucid')]

您现在可以使用元组作为过滤器

最新更新