代码之家  ›  专栏  ›  技术社区  ›  A T

二元分类器keras回调的敏感性和特异性?

  •  1
  • A T  · 技术社区  · 6 年前

    我如何获得敏感性和特异性,当 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
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   today    6 年前

    因为在二进制模式下,您实际上是在预测一个值,该值指示正类的概率(即二进制分类),使用 .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]))
    

    就这样过去 mode=class_mode 打电话时 输出灵敏度 在你的回调中,它对二进制和分类模式都有效。