Python 3.x Scikit学习组ShuffleSplit未按指定组分组
我正在尝试拆分一个农场数据的时间序列,该数据以每天的频率采集8年。我希望分割数据,以便序列和测试集都包含来自不同农场的样本,并且序列和测试集之间没有农场重叠。我在dataframe中创建了一列,其中包含唯一的FarmID,指示样本来自哪个农场 从视觉上看,数据集通常是这样的:Python 3.x Scikit学习组ShuffleSplit未按指定组分组,python-3.x,pandas,scikit-learn,data-science,train-test-split,Python 3.x,Pandas,Scikit Learn,Data Science,Train Test Split,我正在尝试拆分一个农场数据的时间序列,该数据以每天的频率采集8年。我希望分割数据,以便序列和测试集都包含来自不同农场的样本,并且序列和测试集之间没有农场重叠。我在dataframe中创建了一列,其中包含唯一的FarmID,指示样本来自哪个农场 从视觉上看,数据集通常是这样的: df ╔════════╦════════════╦═══════════╦═════╦═══════════╗ ║ FarmID ║ datetime ║ Feature_1 ║ ... ║ Feature_n ║
df
╔════════╦════════════╦═══════════╦═════╦═══════════╗
║ FarmID ║ datetime ║ Feature_1 ║ ... ║ Feature_n ║
╠════════╬════════════╬═══════════╬═════╬═══════════╣
║ 0 ║ 2009-01-01 ║ 45.76 ║ ... ║ 15.12 ║
║ ... ║ ... ║ ... ║ ... ║ ... ║
║ 3668 ║ 2017-12-31 ║ 12.12 ║ ... ║ 15.75 ║
╚════════╩════════════╩═══════════╩═════╩═══════════╝
6702142 rows × 35 columns
df[df.FarmID==0]
╔════════╦════════════╦═══════════╦═════╦═══════════╗
║ FarmID ║ datetime ║ Feature_1 ║ ... ║ Feature_n ║
╠════════╬════════════╬═══════════╬═════╬═══════════╣
║ 0 ║ 2009-01-01 ║ 35.31 ║ ... ║ 67.41 ║
║ ... ║ ... ║ ... ║ ... ║ ... ║
║ 0 ║ 2017-12-31 ║ 2.15 ║ ... ║ 5.21 ║
╚════════╩════════════╩═══════════╩═════╩═══════════╝
1096 rows x 35 columns
# Note: Not all farms contain the same number of samples as some farms didn't submit data in some years.
要拆分数据集,我使用了以下代码:
df = df.sort_values('FarmID')
def group_split(df, test_size=.80, seed=seed):
from sklearn.model_selection import GroupShuffleSplit
gss = GroupShuffleSplit(1, test_size, random_state=seed)
for test_indices, train_indices in gss.split(df, groups=df.FarmID):
train = df.loc[train_indices]
test = df.loc[test_indices]
return train, test
train, test = group_split(df)
在检查列车测试拆分中包含的独特农场后,我发现列车和测试集中都包含一些农场
In: train.FarmID.unique()
Out: array([2.000e+00, 4.000e+00, 8.000e+00, ..., 2.245e+03, 2.229e+03,
2.575e+03])
In: test.FarmID.unique()
Out: array([0.000e+00, 1.000e+00, 1.300e+01, ..., 2.245e+03, 2.229e+03,
2.575e+03])
In: n = 2245
df[df.FarmID==n].shape
train[train.FarmID==n].shape
test[test.FarmID==n].shape
Out: (1826, 35)
(1225, 35)
(601, 35)
然而,有些农场被正确分割
In: n = 3668
df[df.FarmID==n].shape
train[train.FarmID==n].shape
test[test.FarmID==n].shape
Out: (705, 35)
(705, 35)
(0, 35)
此外,3669个农场中有995个在列车测试集中重叠
In: train_FarmIDs = train.FarmID.unique()
test_FarmIDs = test.FarmID.unique()
len(set(train_FarmIDs).intersection(set(test_FarmIDs)))
Out: 995
我完全搞不懂为什么sklearn的GroupShuffleSplit没有按我正确指定的组进行拆分。如果有人能帮我解决这个问题,我将不胜感激 只是猜测,但我认为gss正在将数据帧转换为ndarray,并返回ndarray的位置索引。对df进行排序,这会扰乱df索引,然后使用.loc[]。尝试改用.iloc[],或者在使用gss之前将df转换为numpy数组,然后在numpy数组而不是数据帧上切片。仍然对这个问题感兴趣吗?我明白这个答案;这可能是有问题的“groups=df.FarmID”。它是拾取FarmID还是拾取df的索引?