评估分类模型的正确方法(“ UndefinedMetricWarning:”)

时间:2019-05-21 07:38:40

标签: python keras neural-network categorical-data one-hot-encoding

我目前正在使用一个神经网络,该神经网络输出一个热编码输出。

通过分类报告对其进行评估后,我收到此错误:

UndefinedMetricWarning: Recall and F-score are ill-defined and being set 
to 0.0 in samples with no true labels.

train-test-split阶段对输出进行一次热编码时,为了避免“虚拟变量陷阱”,我不得不删除其中一列。结果,我的神经网络的某些预测为[0, 0, 0, 0],表明它属于第五类。我相信这是UndefinedMetricWarning:的原因。

有解决方案吗?还是应该首先避免分类报告,并且有更好的方法来评估这类神经网络?我对机器学习和神经网络还很陌生,请原谅我的无知。谢谢您的帮助!


编辑#1:

这是我的网络:

from keras.models import Sequential
from keras.layers import Dense

classifier = Sequential()
classifier.add(Dense(units = 10000,
                     input_shape = (30183,),
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )
classifier.add(Dense(units = 4583,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              ) 
classifier.add(Dense(units = 1150,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )    
classifier.add(Dense(units = 292,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )
classifier.add(Dense(units = 77,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )
classifier.add(Dense(units = 23,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )
classifier.add(Dense(units = 7,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'relu'
                    )
              )
classifier.add(Dense(units = 4,
                     kernel_initializer = 'glorot_uniform',
                     activation = 'softmax'
                    )
              )

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

以上是我的网络。训练网络后,我可以预测值,并使用以下方法将其转换为类标签:

from sklearn.preprocessing import LabelBinarizer

labels = np.argmax(predictions, axis = -1)
lb = LabelBinarizer()
labeled_predictions = lb.fit_transform(labels)

调用比较y_testlabeled_predctions的分类报告时,我收到错误消息。

**作为对任何好奇的人的补充,我正在尝试自然语言处理和神经网络。我的网络的输入向量之所以如此之大,是因为它将输入向量化的文本作为其输入的一部分。


编辑#2:

我将预测结果转换为数据帧,并删除了测试集和预测结果的重复项:

y_test.drop_duplicates()

      javascript  python    r   sql
 738           0       0    0     0
4678           1       0    0     0
6666           0       0    0     1
5089           0       1    0     0
6472           0       0    1     0

predictions_df.drop_duplicates()


     javascript python  r   sql
738           1      0  0     0
6666          0      0  0     1
5089          0      1  0     0
3444          0      0  1     0

因此,实质上发生的事情是由于softmax转换为二进制的方式所致,因此预测永远不会产生[0,0,0,0]。当进行热编码y_test时,是否应该不删除第一列?

1 个答案:

答案 0 :(得分:1)

是的,我要说你不应该删除第一列。因为您现在要做的是获取softmax,然后将具有最高值的神经元作为标签(labels = np.argmax(predictions,axis = -1))。使用这种方法,您将永远无法获得[0,0,0,0]结果向量。因此,与其执行此操作,不如创建一个具有所有5类位置的onehot向量。您对sklearn的问题应该消失了,因为您将获得第5堂课带有真实标签的样本。

我也不确定虚拟变量陷阱是否是神经网络的问题。我以前从未听说过此消息,并且简短的Google Scholar搜索未找到任何结果。到目前为止,在所有有关神经网络的资源中,我都从未遇到过这个问题。因此,我猜(但这只是猜测),在训练神经网络时,这并不是一个真正的问题。大多数神经网络最后都使用softmax这一事实也得出了这一结论。