我正在研究一个医疗数据集,我试图减少假阴性。预测“实际上没有疾病时的疾病”对我来说是可以的,但预测“实际上没有疾病时没有疾病”。也就是说,我对FP
没有问题,但没有FN
。
在做了一些研究之后,我发现了像Keeping higher learning rate for one class
,using class weights
,ensemble learning with specificity/sensitivity
等的方法。
我使用像class_weight = {0 : 0.3,1: 0.7}
这样的类权重然后调用model.fit(class_weights=class_weight)
来获得接近期望的结果。这给了我非常低的FN但是相当高的FP。我试图尽可能地降低FP,使FN保持在非常低的水平。
我正在努力使用Keras
编写自定义丢失函数,这将帮助我惩罚假阴性。谢谢您的帮助。
我将简要介绍一下我们试图解决的概念。
从所有积极的方面来看,我们的模型预测有多少是积极的?
所有这些都是积极的=
我们的模型所说的是积极的=
由于召回与FN成反比,因此改善它会降低FN。
从所有负面的,我们的模型预测为负数多少?
所有这些都是负面的=
我们的模型所说的是负面=
由于召回与FP成反比,因此改善它会降低FP。
在您的下一次搜索或您执行的任何与分类相关的活动中,了解这些活动将为您提供沟通和理解的额外优势。
所以。正如你们已经想到的那样,这两个概念是对立的。这意味着增加一个可能会减少另一个。
由于您希望调用优先级,但不希望在特异性方面过于宽松,因此可以将这两者与属性权重结合起来。遵循this answer中明确解释的内容:
import numpy as np
import keras.backend as K
def binary_recall_specificity(y_true, y_pred, recall_weight, spec_weight):
TN = np.logical_and(K.eval(y_true) == 0, K.eval(y_pred) == 0)
TP = np.logical_and(K.eval(y_true) == 1, K.eval(y_pred) == 1)
FP = np.logical_and(K.eval(y_true) == 0, K.eval(y_pred) == 1)
FN = np.logical_and(K.eval(y_true) == 1, K.eval(y_pred) == 0)
# Converted as Keras Tensors
TN = K.sum(K.variable(TN))
FP = K.sum(K.variable(FP))
specificity = TN / (TN + FP + K.epsilon())
recall = TP / (TP + FN + K.epsilon())
return 1.0 - (recall_weight*recall + spec_weight*specificity)
注意recall_weight
和spec_weight
?它们是我们归因于每个指标的权重。对于分发惯例,它们应该总是添加到1.0
¹,例如recall_weight=0.9
,specificity_weight=0.1
。这里的目的是让您了解最适合您需求的比例。
但是Keras的损失函数必须只接收(y_true, y_pred)
作为参数,所以让我们定义一个包装器:
# Our custom loss' wrapper
def custom_loss(recall_weight, spec_weight):
def recall_spec_loss(y_true, y_pred):
return binary_recall_specificity(y_true, y_pred, recall_weight, spec_weight)
# Returns the (y_true, y_pred) loss function
return recall_spec_loss
使用它,我们有
# Build model, add layers, etc
model = my_model
# Getting our loss function for specific weights
loss = custom_loss(recall_weight=0.9, spec_weight=0.1)
# Compiling the model with such loss
model.compile(loss=loss)
¹重量,加上,必须总1.0
,因为如果recall=1.0
和specificity=1.0
(完美的分数),公式
例如,应该给我们
显然,如果我们得到了满分,我们希望我们的损失等于0。