如何将大数据集分成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 number
和np.random.random_sample
,然后您可以group by
class
并将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个子集,保持类比例的主要内容,如果未能解决你的问题,请参考以下文章