如何按照一些准则将数据集拆分为子集?

时间:2019-01-04 17:44:36

标签: python pandas dataframe scikit-learn

尽管我使用与机器学习相关的术语,但我的问题是100%工程主题,与统计和数学无关。因此,我在这个论坛中问这个问题,而不是交叉验证。

这是我的示例数据,将用于评论我的问题:

X = pd.DataFrame(columns=["F1","F2"], 
                  data=[[23,0.8],
                        [11,5.35],
                        [24,19.18],
                        [15,10.25],
                        [10,11.30],
                        [55,44.85],
                        [15,33.88],
                        [12,45.30],
                        [14,22.20],
                        [15,15.80],
                        [83,0.8],
                        [51,5.35],
                        [34,30.28],
                        [35,15.25],
                        [60,13.30],
                        [75,44.80],
                        [35,30.77],
                        [62,40.33],
                        [64,23.40],
                        [14,11.80]])

y = pd.DataFrame(columns=["y"], 
                  data=[[0],
                        [0],
                        [1],
                        [0],
                        [2],
                        [2],
                        [2],
                        [1],
                        [0],
                        [1],
                        [0],
                        [0],
                        [1],
                        [0],
                        [1],
                        [0],
                        [1],
                        [1],
                        [0],
                        [2]])

我应该将数据分为训练和测试集。一种经典方法是使用train_test_split的{​​{1}}函数:

sklearn

但是我想指定要分配给训练和测试集的记录百分比。下面将详细说明。

在我的情况下,我遇到了一个多类分类问题,其中X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size=0.25) 可能采用以下三个值之一:0、1、2。值2的记录非常少(在我的实际情况中数据集,约占整个数据集的3%)。因此,这是一个不平衡的分类问题。

由于这是一个不平衡的分类问题,因此稀有分类的记录非常重要。因此,我想按以下方式更新y:我想为培训和测试集分配每个班级的记录%。 例如,<50%,60%,90%>表示将稀有课程的记录的90%分配给训练集。

在我的示例中,例如,我想获得3个记录model_selection.train_test_split等于训练集中的y2X_train)的记录,并且测试集中有1条记录。

我在Google上搜索了类似的问题,但没有找到任何东西。

为解决此任务,我重新整理了初始数据帧:

y_train

但是,我不知道如何进行其余任务。也许有一些sklearn内置函数或某些库可以解决此问题?

1 个答案:

答案 0 :(得分:2)

train_test_split中有一个名为stratify的选项。也看看这个kind of similar question

要完成所需的比例,可以使用numpy中的np.random.choice

import numpy as np
df = pd.concat([X,y], axis = 1)

#get index values for y = 0
i0 = np.random.choice(df.loc[df.y==0].index.values,
round(len(df.loc[df.y==0])*.5), replace = False)

i1 = np.random.choice(df.loc[df.y==1].index.values,
round(len(df.loc[df.y==1])*.6), replace = False)

i2 = np.random.choice(df.loc[df.y==2].index.values,
round(len(df.loc[df.y==1])*.9), replace = False)

df_train = df.loc[df.index.isin(np.concatenate([i1,i2,i0]))]
df_test = df.loc[~df.index.isin(np.concatenate([i1,i2,i0]))]