如何解决样本不均衡问题

解决样本不均衡的问题很多,主流的几个如下:

1.样本的过采样和欠采样。

2..使用多个分类器进行分类。

3.将二分类问题转换成其他问题。

4.改变正负类别样本在模型中的权重。

 

 

一、样本的过采样和欠采样。

1.过采样:将稀有类别的样本进行复制,通过增加此稀有类样本的数量来平衡数据集。该方法适用于数据量较小的情况。

2.欠抽样:从丰富类别的样本中随机选取和稀有类别相同数目的样本,通过减少丰富类的样本量啦平衡数据集。该方法适用于数据量较大的情况。

3.也可以将过采样和欠采样结合在一起使用。

4.使用SMOTE方法来构造样本。

  SMOTE算法是一种过采样的算法。这个算法不是简单的复制已有的数据,而是在原有数据基础上,通过算法产生新生数据。

  算法思想:基于距离度量的方式计算两个或多个稀有类样本之间的相似性。

       然后选择其中的一个样本作为基础样本,

       再在邻居样本中随机选取一定数量的样本对那个基础样本的一个属性进行噪声。每次处理一个属性,通过这样的方式产生新生数据。

二、使用多个分类器进行分类。

  方法一中介绍的过采样,欠采样,都存在相应的问题。

  过采样:可能会存在过拟合问题。(可以使用SMOTE算法,增加随机的噪声的方式来改善这个问题)

  欠采样:可能会存在信息减少的问题。因为只是利用了一部分数据,所以模型只是学习到了一部分模型。

  有以下两种方法可以解决欠采样所带来的问题。

  方法一:模型融合 (bagging的思想 )

  思路:从丰富类样本中随机的选取(有放回的选取)和稀有类等量样本的数据。和稀有类样本组合成新的训练集。这样我们就产生了多个训练集,并且是互相独立的,然后训练得到多个分类器。

     若是分类问题,就把多个分类器投票的结果(少数服从多数)作为分类结果。

     若是回归问题,就将均值作为最后结果。

  方法二:增量模型 (boosting的思想)

  思路:使用全部的样本作为训练集,得到分类器L1

     从L1正确分类的样本中和错误分类的样本中各抽取50%的数据,即循环的一边采样一个。此时训练样本是平衡的。训练得到的分类器作为L2.

     从L1和L2分类结果中,选取结果不一致的样本作为训练集得到分类器L3.

     最后投票L1,L2,L3结果得到最后的分类结果。

三、将二分类问题转换成其他问题。

  可以将不平衡的二分类问题转换成异常点检测,或者一分类问题(可使用one-class svm建模)

四、改变正负类别样本在模型中的权重。

  使用代价函数学习得到每个类的权值,大类的权值小,小类的权值大。刚开始,可以设置每个类别的权值与样本个数比例的倒数,然后可以使用过采样进行调优。

五、注意点:

  1.不平衡问题的评价指标

  准确度这个评价指标在类别不均衡的分类任务中并不能work。几个比传统的准确度更有效的评价指标:

  混淆矩阵(Confusion Matrix):使用一个表格对分类器所预测的类别与其真实的类别的样本统计,分别为:TP、FN、FP与TN。
  精确度(Precision)
  召回率(Recall)
  F1得分(F1 Score):精确度与找召回率的加权平均。
  特别是:

  Kappa (Cohen kappa)
  ROC曲线(ROC Curves):见Assessing and Comparing Classifier Performance with ROC Curves

  2.交叉验证

  在K-Fold 校验中,每一份数据集中原则上应该保持类别样本比例一样或者近似,如果每份数据集中小类样本数目过少,那么应该降低K的值,知道小类样本的个数足够。

转载于:https://www.cnblogs.com/lyr2015/p/8711120.html

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一段GAN代码,用于解决样本不均问题: ``` import tensorflow as tf from tensorflow.keras import layers # 定义生成器模型 def make_generator_model(): model = tf.keras.Sequential() model.add(layers.Dense(256, input_shape=(100,), use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dense(512, use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dense(1024, use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dense(784, activation='tanh')) return model # 定义判别器模型 def make_discriminator_model(): model = tf.keras.Sequential() model.add(layers.Dense(1024, input_shape=(784,), use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dropout(.3)) model.add(layers.Dense(512, use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dropout(.3)) model.add(layers.Dense(256, use_bias=False)) model.add(layers.BatchNormalization()) model.add(layers.LeakyReLU()) model.add(layers.Dropout(.3)) model.add(layers.Dense(1)) return model # 定义损失函数 cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True) # 定义生成器损失函数 def generator_loss(fake_output): return cross_entropy(tf.ones_like(fake_output), fake_output) # 定义判别器损失函数 def discriminator_loss(real_output, fake_output): real_loss = cross_entropy(tf.ones_like(real_output), real_output) fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output) total_loss = real_loss + fake_loss return total_loss # 定义优化器 generator_optimizer = tf.keras.optimizers.Adam(1e-4) discriminator_optimizer = tf.keras.optimizers.Adam(1e-4) # 定义训练函数 @tf.function def train_step(images): noise = tf.random.normal([BATCH_SIZE, 100]) with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape: generated_images = generator(noise, training=True) real_output = discriminator(images, training=True) fake_output = discriminator(generated_images, training=True) gen_loss = generator_loss(fake_output) disc_loss = discriminator_loss(real_output, fake_output) gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables) gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables) generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables)) discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables)) # 定义训练过程 def train(dataset, epochs): for epoch in range(epochs): for image_batch in dataset: train_step(image_batch) # 加载数据集 (train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data() train_images = train_images.reshape(train_images.shape[], 784).astype('float32') train_images = (train_images - 127.5) / 127.5 # 将像素值归一化到[-1, 1]之间 BUFFER_SIZE = 60000 BATCH_SIZE = 256 train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE) # 创建生成器和判别器 generator = make_generator_model() discriminator = make_discriminator_model() # 训练模型 EPOCHS = 50 train(train_dataset, EPOCHS) ``` 这段代码使用了生成对抗网络(GAN)来解决样本不均问题。GAN由一个生成器和一个判别器组成,生成器用于生成假样本,判别器用于判断样本是真实的还是假的。在训练过程中,生成器和判别器相互竞争,最终生成器可以生成与真实样本相似的假样本。这种方法可以用于解决样本不均问题,因为生成器可以生成更多的少数类样本,从而平数据集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值