【发布时间】:2019-12-25 02:22:23
【问题描述】:
我有一个数据集,其中包含多个测试系统,每个系统都重复了测试。
所有系统的副本总数是恒定的(平衡的),但每个副本可能包含不同数量的总观测值。
我想使用交叉验证将数据拆分为训练集和测试集,这样:
- 测试和训练集中的每个系统
- 训练集将包含每个系统的除 1 个副本之外的所有副本,而测试集包含每个系统的剩余副本
- 测试集中每个系统的观察百分比与训练集中每个系统的观察百分比相匹配
我希望使用 sci-kit learn 的 StratifiedKFold 功能,但它似乎无法满足我的需求。
例如,使用此示例标记数据:
labels=np.concatenate([['Sys1']*35,['Sys2']*33,['Sys3']*36])
reps=np.concatenate([
np.concatenate([
['Rep_0']*10,['Rep_1']*10,['Rep_2']*5,['Rep_3']*10]),
np.concatenate([
['Rep_0']*8,['Rep_1']*10,['Rep_2']*10,['Rep_3']*5]),
np.concatenate([
['Rep_0']*10,['Rep_1']*7,['Rep_2']*9,['Rep_3']*10])
])
frames=np.concatenate([
np.concatenate([
np.arange(10),np.arange(10),np.arange(5),np.arange(10)]),
np.concatenate([
np.arange(8),np.arange(10),np.arange(10),np.arange(5)]),
np.concatenate([
np.arange(10),np.arange(7),np.arange(9),np.arange(10)])
])
sampleKeys=np.array(map(lambda x,y: '.'.join([x,y]),
labels,
reps))
我尝试拆分标签:
cvSplitter=skl.model_selection.StratifiedKFold(n_splits=4)
iSplit=0
for train_indices, test_indices in cvSplitter.split(labels,labels):
print '--- split %g ---'%iSplit
print 'TRAIN:'
for sample in np.array([np.unique(sampleKeys[train_indices],return_counts=True)[0],
np.unique(sampleKeys[train_indices],return_counts=True)[1]]).T:
print sample
print 'TEST:'
for sample in np.array([np.unique(sampleKeys[test_indices],return_counts=True)[0],
np.unique(sampleKeys[test_indices],return_counts=True)[1]]).T:
print sample
iSplit=iSplit+1
但是,虽然结果包含来自每个系统的训练与测试中相同百分比的观察结果,但训练集包含某些或所有系统的所有副本,而我希望训练集包含除一个副本之外的所有副本,而测试集包含缺少副本。
--- split 0 ---
TRAIN:
['Sys1.Rep_0' '1']
['Sys1.Rep_1' '10']
['Sys1.Rep_2' '5']
['Sys1.Rep_3' '10']
['Sys2.Rep_1' '9']
['Sys2.Rep_2' '10']
['Sys2.Rep_3' '5']
['Sys3.Rep_0' '1']
['Sys3.Rep_1' '7']
['Sys3.Rep_2' '9']
['Sys3.Rep_3' '10']
TEST:
['Sys1.Rep_0' '9']
['Sys2.Rep_0' '8']
['Sys2.Rep_1' '1']
['Sys3.Rep_0' '9']
--- split 1 ---
TRAIN:
['Sys1.Rep_0' '9']
['Sys1.Rep_1' '2']
['Sys1.Rep_2' '5']
['Sys1.Rep_3' '10']
['Sys2.Rep_0' '8']
['Sys2.Rep_1' '2']
['Sys2.Rep_2' '10']
['Sys2.Rep_3' '5']
['Sys3.Rep_0' '9']
['Sys3.Rep_2' '8']
['Sys3.Rep_3' '10']
TEST:
['Sys1.Rep_0' '1']
['Sys1.Rep_1' '8']
['Sys2.Rep_1' '8']
['Sys3.Rep_0' '1']
['Sys3.Rep_1' '7']
['Sys3.Rep_2' '1']
--- split 2 ---
TRAIN:
['Sys1.Rep_0' '10']
['Sys1.Rep_1' '8']
['Sys1.Rep_3' '8']
['Sys2.Rep_0' '8']
['Sys2.Rep_1' '9']
['Sys2.Rep_2' '3']
['Sys2.Rep_3' '5']
['Sys3.Rep_0' '10']
['Sys3.Rep_1' '7']
['Sys3.Rep_2' '1']
['Sys3.Rep_3' '9']
TEST:
['Sys1.Rep_1' '2']
['Sys1.Rep_2' '5']
['Sys1.Rep_3' '2']
['Sys2.Rep_1' '1']
['Sys2.Rep_2' '7']
['Sys3.Rep_2' '8']
['Sys3.Rep_3' '1']
--- split 3 ---
TRAIN:
['Sys1.Rep_0' '10']
['Sys1.Rep_1' '10']
['Sys1.Rep_2' '5']
['Sys1.Rep_3' '2']
['Sys2.Rep_0' '8']
['Sys2.Rep_1' '10']
['Sys2.Rep_2' '7']
['Sys3.Rep_0' '10']
['Sys3.Rep_1' '7']
['Sys3.Rep_2' '9']
['Sys3.Rep_3' '1']
TEST:
['Sys1.Rep_3' '8']
['Sys2.Rep_2' '3']
['Sys2.Rep_3' '5']
['Sys3.Rep_3' '9']
1
如果我改为拆分“reps”,我最终会发现一些系统被排除在测试和/或训练数据之外。
【问题讨论】: