Keras中的不平衡数据集问题

5

我正在使用Python和Keras库构建分类神经网络。 我正在使用三个不同类别的不平衡数据集来训练NN。 类1的普及率大约是类2和类3的7.5倍。 为了解决这个问题,我采取了这个stackoverflow答案的建议,并设置了我的类权重如下:

class_weight = {0 : 1,
                1 : 6.5,
                2: 7.5}

然而,这里有一个问题:ANN以相等的频率预测3个类!这是没有用的,因为数据集不平衡,在预测结果每个类的概率都是33%时是不准确的。问题是:如何处理不平衡的数据集,使得ANN不会每次都预测类别1,但也不会以相等的概率预测其他类别?以下是我正在使用的代码:
class_weight = {0 : 1,
1 : 6.5,
2: 7.5}

# Making the ANN
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout

classifier = Sequential()


# Adding the input layer and the first hidden layer with dropout
classifier.add(Dense(activation = 'relu',
                     input_dim = 5,
                     units = 3,
                     kernel_initializer = 'uniform'))
#Randomly drops 0.1, 10% of the neurons in the layer.
classifier.add(Dropout(rate= 0.1))

#Adding the second hidden layer
classifier.add(Dense(activation = 'relu',
                     units = 3,
                     kernel_initializer = 'uniform'))
#Randomly drops 0.1, 10% of the neurons in the layer.
classifier.add(Dropout(rate = 0.1)) 

# Adding the output layer
classifier.add(Dense(activation = 'sigmoid',
                     units = 2,
                     kernel_initializer = 'uniform'))

# Compiling the ANN
classifier.compile(optimizer = 'adam',
                   loss = 'binary_crossentropy',
                   metrics = ['accuracy'])

# Fitting the ANN to the training set
classifier.fit(X_train, y_train, batch_size = 100, epochs = 100, class_weight = class_weight)

在我回答之前,我需要更多的信息:训练数据的形状是什么?标签如何编码?一个样本是否可以同时属于多个类别? - Daniele Grattarola
2个回答

7
我看到你的模型最明显的问题是没有正确的分类结构。如果你的样本每次只能属于一个类别,那么你不应该使用sigmoid激活作为最后一层来忽略这个事实。
理想情况下,分类器的最后一层应该输出样本属于某个类别的概率,即(在你的情况下)一个数组[a,b,c],其中[a + b + c == 1]。
如果你使用sigmoid输出,那么输出[1,1,1]是可能的,尽管这不是你想要的。这也是你的模型不能正确泛化的原因:由于你没有专门训练它优先选择“不平衡”的输出(如[1,0,0]),所以它会默认预测其在训练期间看到的平均值,从而考虑重新加权。
尝试将最后一层的激活改为“softmax”,将损失改为“categorical_crossentropy”。
# Adding the output layer
classifier.add(Dense(activation='softmax',
                     units=2,
                     kernel_initializer='uniform'))

# Compiling the ANN
classifier.compile(optimizer='adam',
                   loss='categorical_crossentropy',
                   metrics=['accuracy'])

如果这行不通,请看看我的另一个评论,并使用那些信息与我联系,但我相信这是主要问题。
祝好。

0

在分类中,不平衡的数据集(其中类别不均或分布不均)是一个普遍存在的问题。例如,一个类别标签具有非常高的观测数量,而另一个类别标签具有相对较低的观测数量。导致数据不平衡的重要原因包括:

  • 错误的数据收集
  • 领域特殊性 - 当某些领域具有不平衡的数据集时。

不平衡的数据集可能会在分类中产生许多问题,因此需要改进数据集以获得强大的模型和提高性能。

以下是几种方法可以使不平衡的数据集达到平衡:

欠采样 - 通过重新采样数据集中的多数类点来匹配或使它们等于少数类点。它在多数类和少数类之间建立平衡,使分类器对两个类别都给予同等重视。但是,需要注意的是,欠采样可能会导致一些信息丢失,从而产生一些无关紧要的结果。

过采样 - 也称为上采样,过采样重新采样少数类,使其等于多数类点的总数。它复制了来自少数类点的观测结果以平衡数据集。

合成少数类过采样技术 - 顾名思义,SMOTE技术使用过采样来为少数类创建人工数据点。它在少数类属性之间创建新实例,这些实例是从现有数据中合成的。

从网格中搜索最优值 - 此技术涉及找到特定类标签的概率,然后找到将可能性映射到正确类标签的最佳阈值。

使用BalancedBaggingClassifier - BalancedBaggingClassifier允许您在训练随机估计器以创建平衡数据集之前对数据集的每个子类进行重新采样。

使用不同的算法 - 一些算法在恢复不平衡数据集的平衡方面并不有效。有时候尝试不同的算法可以更好地创造平衡的数据集并提高性能。例如,您可以使用正则化或惩罚模型来惩罚对少数类的错误预测。

不平衡数据集的影响可能很大。希望以上方法之一可以帮助您朝正确的方向发展。

为了测试哪种方法最适合您,我建议使用deepchecks,这是一个用于快速验证数据和模型的很棒的开放式Python包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接