python - 二元分类器 Keras 回调的敏感性和特异性?

标签 python numpy tensorflow scikit-learn keras

class_mode='binary'时,如何获得敏感性和特异性? - 我当前的解决方案适用于 class_mode='categorical':

from keras.callbacks import Callback
import numpy as np
from sklearn.metrics import confusion_matrix


class SensitivitySpecificityCallback(Callback):
    def on_epoch_end(self, epoch, logs=None):
        if epoch:
            x_test, y_test = self.validation_data[0], self.validation_data[1]
            predictions = self.model.predict(x_test)
            output_sensitivity_specificity(epoch, predictions, y_test)


def output_sensitivity_specificity(epoch, predictions, y_test):
    y_test = np.argmax(y_test, axis=-1)
    predictions = np.argmax(predictions, axis=-1)
    c = confusion_matrix(y_test, predictions)
    print('Confusion matrix:\n', c)
    print('[{:03d}] sensitivity'.format(epoch), c[0, 0] / (c[0, 1] + c[0, 0]))
    print('[{:03d}] specificity'.format(epoch), c[1, 1] / (c[1, 1] + c[1, 0]))

82 source lines full code example (Python 2 和 3 兼容)

所有输出都是错误的:

Confusion matrix:
 [[40]]
Traceback (most recent call last):
  File "network.py", line 118, in <module>
    callbacks=[SensitivitySpecificityCallback()], verbose=1)
  File "lib/python2.7/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "lib/python2.7/site-packages/keras/engine/training.py", line 1426, in fit_generator
    initial_epoch=initial_epoch)
  File "lib/python2.7/site-packages/keras/engine/training_generator.py", line 229, in fit_generator
    callbacks.on_epoch_end(epoch, epoch_logs)
  File "lib/python2.7/site-packages/keras/callbacks.py", line 77, in on_epoch_end
    callback.on_epoch_end(epoch, logs)
  File "network.py", line 56, in on_epoch_end
    output_sensitivity_specificity(epoch, predictions, y_test)
  File "network.py", line 64, in output_sensitivity_specificity
    print('[{:03d}] sensitivity'.format(epoch), c[0, 0] / (c[0, 1] + c[0, 0]))
IndexError: index 1 is out of bounds for axis 1 with size 1

最佳答案

由于在二元模式下,您本质上是在预测一个值,该值指示正类的概率(即二元分类),因此在预测中使用 .argmax() 始终返回 0 。因此,您需要针对这种情况修改 output_sensitivity_specificity 函数:

def output_sensitivity_specificity(epoch, predictions, y_test, mode='binary'):
    if mode == 'binary':
        # determine positive class predictions
        idx = predictions >= 0.5
        predictions = np.zeros(predictions.shape)
        predictions[idx] = 1
        # no need to modify y_test since it consists of zeros and ones already
    else:
        y_test = np.argmax(y_test, axis=-1)
        predictions = np.argmax(predictions, axis=-1)

    c = confusion_matrix(y_test, predictions)
    print('Confusion matrix:\n', c)
    print('[{:03d}] sensitivity'.format(epoch), c[0, 0] / (c[0, 1] + c[0, 0]))
    print('[{:03d}] specificity'.format(epoch), c[1, 1] / (c[1, 1] + c[1, 0]))

只需在回调中调用 output_sensitivity_specificity 时传递 mode=class_mode ,它就适用于二进制和分类模式。

关于python - 二元分类器 Keras 回调的敏感性和特异性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51298992/

相关文章:

python - 从任意嵌套的 HTML 中提取所有文本

python - 压缩到python中的特定目录

python - Django 管理表单字段 - 在选择框中显示对象相关的查询结果

python - 给定空间中的三个点(3D)找到弧/圆方程

multithreading - tensorflow-serving 支持多线程吗?

python - 在 python 代码中使用 http.server 命令行

python - 在 numpy 中重复 matlab dyadup

python - 当作为指标传递给 model.compile() 时,tf.keras.metrics.TruePositives() 在 model.fit() 中返回错误值

python - Tensorflow Metal 插件已注册错误

python - numpy,合并两个不同形状的数组