我有一个Pandas数据帧:comb
ENROLLED_Response
条目的数量非常少,因此仅对整个DataFrame进行随机采样可能会丢失太多注册数据。
解决方案是对ENROLLED_Response == True
所在的所有条目进行75%的采样然后对ENROLLED_Response == False
所在的所有条目进行70%的采样
所以我应该在DataFrame 上得到一个列is_train
和true
/false
所以我通常使用这样的东西:
from sklearn.cross_validation import cross_val_score
#split the dataset for train and test
comb['is_train'] = np.random.uniform(0, 1, len(comb)) <= .75
train, test = comb[comb['is_train']==True], comb[comb['is_train']==False]
对于大多数情况来说,这是可以的,但由于注册人数较少,这种方法往往会遗漏太多的"注册"人员,因为他们太少了。所以我需要的是更像的东西
comb['is_train'] = train_test_split(comb['ENROLLED_Response']==True, Train_size = 0.75)
comb['is_train']= train_test_split(comb['ENROLLED_Response']==False, Train_size = 0.75)
这当然是行不通的。其概念是:首先对已登记的人进行抽样,并随机将其中.75人标记为训练,然后对未登记的人(其他所有人)进行抽样,将其中.755人标记为培训,在同一个新列(is_train)中,这样它就可以很容易地在Scikit_learn中使用,比如:
train, test = comb[comb['is_train']==True],comb[comb['is_train']==False]
无法弄清楚如何做到这一点,因为随机生成的np数组是关于整个DataFrame的长度(以及其他问题…)
评论后更新:
import pandas as pd
import numpy as np
np.random.seed(42)
truePct = 0.75
falsePct = 0.70
comb = pd.DataFrame({
"feat1": np.random.randint(low=1, high=4, size=20),
"feat2": np.random.randint(low=1, high=4, size=20),
"ENROLLED_Response": np.random.randint(low=0, high=4, size=20)==3
})
# Set train to False by default
comb['train'] = False
# Create two permutations for both classes
nTrue = comb[comb.ENROLLED_Response==True].shape[0]
nFalse = comb[comb.ENROLLED_Response==False].shape[0]
truePerm = np.random.permutation(nTrue)[:int(np.floor(truePct*nTrue)-1)]
falsePerm = np.random.permutation(nFalse)[:int(np.floor(falsePct*nFalse)-1)]
# Select the indices
trainTrueIndex = comb[comb.ENROLLED_Response==True].index[truePerm].values.tolist()
trainFalseIndex = comb[comb.ENROLLED_Response==False].index[falsePerm].values.tolist()
comb.loc[trainTrueIndex,'train'] = True
comb.loc[trainFalseIndex,'train'] = True
print comb
中的结果
ENROLLED_Response feat1 feat2 train
0 False 3 1 False
1 False 1 1 False
2 False 3 2 False
3 False 3 2 False
4 False 1 1 True
5 False 1 1 True
6 False 3 1 True
7 True 2 3 True
8 False 3 3 False
9 True 3 3 True
10 False 3 2 True
11 False 3 3 True
12 False 1 2 True
13 False 3 2 True
14 False 2 3 False
15 False 1 2 True
16 False 2 3 True
17 True 2 3 False
18 True 2 1 False
19 False 2 3 True
我不完全相信我正确地解释了你的问题,但你似乎在处理ENROLLED_Response
变量中的类不平衡。为了在训练集和测试集中保持类不平衡,您可能需要使用不同的Scikit学习交叉验证功能:StratifiedHuffleSplit
这个函数是StratifiedKFold和ShuffleSplit的合并,它返回分层随机折叠。通过保留每个类别的样本百分比来进行折叠