首页 > 解决方案 > 如何确保某个数据点不在分层交叉验证拆分的测试集中?

问题描述

我有一个看起来像这样的 DataFrame。

d = {'col1': [1, 2,3,4,5,6,7,8], 'col2': ['a', 'a','b', 'b', 'c', 'c', 'd', 'd']}
df = pd.DataFrame(data=d)
df

  col1  col2
0   1     a
1   2     a
2   3     b
3   4     b
4   5     c
5   6     c
6   7     d
7   8     d

当我使用k-fold cross validation时,我想确保 col2 中的值仅存在于训练集中或测试集中。也就是说,在拆分过程中,如果df['col2'][0] = adf['col2'][1] = a,则索引为 0 和 1 的行都应该在训练集中,否则在测试集中。不应该是第 0 行在训练集中,第 1 行在测试集中。

是否有捷径可寻?

编辑:有没有办法将 DataFrame 分成两部分,这样每个部分都包含在第一个 DataFrame 或第二个 DataFrame 中具有值但不是两者都有的所有数据acol2?我尝试使用groupby但它返回一个对象,当我将它转换为字典时,我只能通过键访问它,即a, b, c, d

标签: pythonpandasscikit-learncross-validation

解决方案


您可以通过执行以下操作来确保变量值仅存在于集合GroupShuffleSplit中:

from sklearn.model_selection import GroupShuffleSplit

import pandas as pd

d = {'col1': [1, 2,3,4,5,6,7,8],
    'col2': ['a', 'a','b', 'b', 'c', 'c', 'd', 'd'],
    'label': [1,1,1,1,0,0,0,0]}
df = pd.DataFrame(data=d)

X = df[['col1', 'col2']]
y = df['label']
groups= df['col2']
gss = GroupShuffleSplit(n_splits=2, train_size=.8, random_state=42)
for train_idx, test_idx in gss.split(X, y, groups):
    X_train, X_test = X.iloc[train_idx], X.iloc[test_idx]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]

推荐阅读