如何将大数据集分成n个子集,保持类比例

Posted

技术标签:

【中文标题】如何将大数据集分成n个子集,保持类比例【英文标题】:How to divide large data set into n subsets mantaining the class proportion 【发布时间】:2019-09-10 05:20:36 【问题描述】:

我正在研究一个二元分类问题,并且我正在使用一个大型数据集(样本数量很大,特征不多)。数据不平衡,但我正在使用一个权重数组来解决这个问题(有点)。

我在这个集合的一个小版本中尝试了一些带有 sklearn 的分类器,显然 SVM 对我想要的效果很好。但是,一旦我尝试在整个数据集中安装一个 SVM,就需要很长时间(而且我的内存也用完了)。

我想知道的是,Sklearn 中是否有任何快速的方法来划分这个集合,比如说 10 个子集,保持类的比例,那么我可以将每个子集划分为训练/测试并适合每个子集独立的 SVM(所以我也可以使用不同的处理器)?

【问题讨论】:

【参考方案1】:

您可以添加一个new column,这将是一个从0到1的random numbernp.random.random_sample,然后您可以group byclass并将pd.cut应用于生成的随机数,例如创建一个新专栏dataset:

df = pd.DataFrame('class': np.random.choice(['A', 'B'], 100), 
               'value': np.random.random_sample(100))
df['dataset'] = pd.DataFrame(df.groupby('class').apply(lambda x: 
pd.cut(x['value'], 10, labels=range(0, 10)))).reset_index(0, drop=True)

【讨论】:

我想你忘了考虑标签分布中存在的不平衡。您不应该以这种方式对数据进行统一采样。更好的方法是将正面和负面分开,并以对每组我们有相等的正面和负面的方式进行采样 不,我没有忘记。按类别分组负责保持每个数据集中的类别比例。【参考方案2】:

StratifiedKFold 功能可以满足您的要求。它将数据分成k个分层折叠。拨打_iter_test_masks()_make_test_folds()

基于documentation:

>>> from sklearn.model_selection import StratifiedKFold
>>> X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])
>>> y = np.array([0, 0, 1, 1])
>>> skf = StratifiedKFold(n_splits=2, shuffle=True)
>>> for i in skf._iter_test_masks(X, y):
...     print(i)

[ True False False  True]
[False  True  True False]

>>> for i in skf._make_test_folds(X, y):
...     print(i)

1
0
0
1

【讨论】:

这与我正在寻找的相似。我可以将 1 个拆分为 5 个折叠,这样我就可以将我的整个数据集分成 5 个相等的部分,然后将它们独立分配给不同的 df? 事实上,StratifiedKfold 只进行了一次拆分。 .split() 为 CV 提供了一个迭代器;在每次迭代中,保留一个折叠作为测试折叠。由于您需要单独测试折叠,请尝试我的更新答案

以上是关于如何将大数据集分成n个子集,保持类比例的主要内容,如果未能解决你的问题,请参考以下文章

将大数据集读取到Jupyter Notebook和Manipulate

R:训练数据集的 k 折交叉验证

将大 csv 转换为 hdf5

如何避免将大文件重复加载到 python 脚本中?

按日期将pyspark数据集分成两个[重复]

当我有高度不平衡的数据时,我应该平衡测试集吗?