评估分类模型的正确方法 ('UndefinedMetricWarning:')
Proper way to evaluate classification model ('UndefinedMetricWarning:')
我目前使用的神经网络输出一个热编码输出。
在使用 class化验报告对其进行评估后,我收到此错误:
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:
的原因。
有解决办法吗?或者我应该首先避免 classification 报告,是否有更好的方法来评估这些类型的神经网络?我对机器学习和神经网络还很陌生,请原谅我的无知。谢谢大家的帮助!!
编辑 #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'])
以上是我的网络。训练网络后,我预测值并将它们转换为 class 标签,使用:
from sklearn.preprocessing import LabelBinarizer
labels = np.argmax(predictions, axis = -1)
lb = LabelBinarizer()
labeled_predictions = lb.fit_transform(labels)
在调用比较 y_test
和 labeled_predctions
的 class化验报告时,我收到错误。
** 作为任何好奇的旁注,我正在试验自然语言处理和神经网络。我的网络的输入向量如此之大的原因是它将计数向量化的文本作为其输入的一部分。
编辑#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
时,我是否应该不删除第一列?
是的,我会说您不应该删除第一列。因为你现在做的是得到softmax,然后取最高值的神经元作为label (labels = np.argmax(predictions, axis = -1) )。使用这种方法,您永远无法获得 [0,0,0,0] 结果向量。因此,与其这样做,不如创建一个 onehot 向量,其中包含所有 5 classes 的位置。你对 sklearn 的问题应该会消失,因为你会为你的第 5 个 class.
获得带有真实标签的样本
我也不确定虚拟变量陷阱是否是神经网络的问题。我以前从未听说过这个,简短的 google 学者搜索没有找到任何结果。此外,在我迄今为止看到的所有关于神经网络的资源中,我从未见过这个问题。所以我猜想(但这真的只是一个猜测),这并不是你在训练神经网络时遇到的真正问题。这个结论也是由大多数神经网络最后使用 softmax 这一事实驱动的。
我目前使用的神经网络输出一个热编码输出。
在使用 class化验报告对其进行评估后,我收到此错误:
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:
的原因。
有解决办法吗?或者我应该首先避免 classification 报告,是否有更好的方法来评估这些类型的神经网络?我对机器学习和神经网络还很陌生,请原谅我的无知。谢谢大家的帮助!!
编辑 #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'])
以上是我的网络。训练网络后,我预测值并将它们转换为 class 标签,使用:
from sklearn.preprocessing import LabelBinarizer
labels = np.argmax(predictions, axis = -1)
lb = LabelBinarizer()
labeled_predictions = lb.fit_transform(labels)
在调用比较 y_test
和 labeled_predctions
的 class化验报告时,我收到错误。
** 作为任何好奇的旁注,我正在试验自然语言处理和神经网络。我的网络的输入向量如此之大的原因是它将计数向量化的文本作为其输入的一部分。
编辑#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
时,我是否应该不删除第一列?
是的,我会说您不应该删除第一列。因为你现在做的是得到softmax,然后取最高值的神经元作为label (labels = np.argmax(predictions, axis = -1) )。使用这种方法,您永远无法获得 [0,0,0,0] 结果向量。因此,与其这样做,不如创建一个 onehot 向量,其中包含所有 5 classes 的位置。你对 sklearn 的问题应该会消失,因为你会为你的第 5 个 class.
获得带有真实标签的样本我也不确定虚拟变量陷阱是否是神经网络的问题。我以前从未听说过这个,简短的 google 学者搜索没有找到任何结果。此外,在我迄今为止看到的所有关于神经网络的资源中,我从未见过这个问题。所以我猜想(但这真的只是一个猜测),这并不是你在训练神经网络时遇到的真正问题。这个结论也是由大多数神经网络最后使用 softmax 这一事实驱动的。