美文网首页机器学习
如何处理不平衡数据集(附代码)

如何处理不平衡数据集(附代码)

作者: 生信阿拉丁 | 来源:发表于2021-06-15 21:29 被阅读0次

    作者:童蒙
    编辑:amethyst

    上一篇中,我们给大家介绍了featuretools这个工具,可以很快速的根据数据的特征来生成各种新的数据组合,之后进行机器学习或者深度学习。这次我们给大家介绍在特征工程中,经常遇到的另一个问题的解决方法。这个问题就是不平衡数据集。

    数据不平衡通常反映了数据集中类别的不均匀分布。比如在一个疾病的预测模型中,对照组可能有两百个,而疾病组只有二十个,数据不平衡比例达到10:1。如果不对数据集进行平衡,那么在后续的MLP抽样中,就会导致算法达不到收敛。因此,我们需要对不平衡数据集进行处理,下面我们来介绍三种方法,两个包,来解决这个办法。

    一、欠采样

    欠采样就是一个随机删除一部分多数类(数量多的类型)数据的过程,这样可以使多数类数据数量可以和少数类(数量少的类型)相匹配。

    首先我们来生成一套数据

    from sklearn.datasets import load_iris
    from imblearn.datasets import make_imbalance
    iris = load_iris(as_frame=True)
    
    sampling_strategy = {0: 10, 1: 20, 2: 47}
    X, y = make_imbalance(iris.data, iris.target, sampling_strategy=sampling_strategy)
    y.value_counts()
    

    可以看到各个类别的个数,类别与{0: 10, 1: 20, 2: 47} 一致。下面我们拿这个数据进行下一步的分析。

    方法1 可以用imblearn的 字符串方法 来进行欠采样

    from imblearn.under_sampling import RandomUnderSampler
    sampling_strategy = "not minority"
    rus = RandomUnderSampler(sampling_strategy=sampling_strategy)
    X_res, y_res = rus.fit_resample(X, y)
    y_res.value_counts()
    

    可以看到结果为:

    2    10
    1    10
    0    10
    

    其中 sampling_strategy可以选择以下几种,大家可以去试试:

    • 'majority':resample only the majority class;
    • 'not minority':resample all classes but the minority class;
    • 'not majority':resample all classes but the majority class;
    • 'all':resample all classes;
    • 'auto':equivalent to 'not minority'。

    方法2 使用dict方法
    使用方法如下:

    from imblearn.under_sampling import RandomUnderSampler
    sampling_strategy = {0: 10, 1: 15, 2: 20}
    rus = RandomUnderSampler(sampling_strategy=sampling_strategy)
    X_res, y_res = rus.fit_resample(X, y)
    y_res.value_counts()
    

    结果如下

    2    20
    1    15
    0    10
    

    可以看出,是按照dict指定的比例来。

    二、过采样

    这是一个生成合成数据的过程,通过学习少数类样本特征随机地生成新的少数类样本数据。

    有许多方法对数据集进行过采样,最常见的技术是SMOTE(Synthetic Minority Over-sampling Technique)。使用方法也很简单,如下:

    方法1 可以用imblearn的 字符串方法 来进行过采样

    from imblearn.over_sampling import RandomOverSampler
    sampling_strategy = "not majority"
    ros = RandomOverSampler(sampling_strategy=sampling_strategy)
    X_res, y_res = ros.fit_resample(X, y)
    y_res.value_counts()
    

    可以看到结果为:

    2    47
    1    47
    0    47
    

    其中 sampling_strategy可以选择以下几种,大家可以去试试:

    • 'minority':resample only the minority class;
    • 'not minority':resample all classes but the minority class;
    • 'not majority':resample all classes but the majority class;
    • 'all':resample all classes;
    • 'auto':equivalent to 'not majority'。

    方法2 使用dict方法
    使用方法如下:

    from imblearn.over_sampling import RandomOverSampler
    sampling_strategy = {0: 25, 1: 35, 2: 47}
    ros = RandomOverSampler(sampling_strategy=sampling_strategy)
    X_res, y_res = ros.fit_resample(X, y)
    y_res.value_counts()
    

    结果如下

    2    47
    1    35
    0    25
    

    可以看出,是按照dict指定的比例来。

    三、使用pytorch集成的抽样方法来调整

    如果大家习惯用torch的话,可以使用如下脚本:

    import torch
    import torch.utils.data as Data
    X_torch = torch.from_numpy(X.values).float()
    y_torch = torch.from_numpy(y.values).float()
    class_sample_count = torch.tensor([(y_torch == t).sum() for t in torch.unique(y_torch, sorted=True)])
    weight = 1. / class_sample_count.float()
    sample_weight = torch.tensor([weight[int(t)] for t in y])
    sampler = torch.utils.data.sampler.WeightedRandomSampler(sample_weight , len(samples_weight))
    train_data = Data.TensorDataset(X,y)
    train_loader = Data.DataLoader( dataset = train_data , batch_size =200  ,sampler = sampler )
    

    使用WeightedRandomSampler来进行进行不平衡抽样。

    结语

    相信大家对如何处理不平衡数据有了一定的了解,请大家以后继续关注我们相关系列。

    参考阅读

    相关文章

      网友评论

        本文标题:如何处理不平衡数据集(附代码)

        本文链接:https://www.haomeiwen.com/subject/evtaeltx.html