Keras 中的不平衡二进制数据集。在拟合 st 灵敏度和特异性最大化后找到最佳阈值?

数据挖掘 Python 喀拉斯 张量流
2022-02-23 17:06:41

我在 Keras 中制作了一个适用于不平衡二进制数据集的 ANN。在拟合模型后使用数据来预测二元类,我想选择一个阈值 st 灵敏度和特异性最大化。

这是我现在正在使用的代码,从 0-1 遍历所有阈值,并使用 G-mean 分数找到最佳阈值。

predictions = model_p.predict(Xt)
thresholds = arange(0, 1, 0.001)
threshold = -1
best_Gscore = 0
false_positive = 0
true_positive = 0
false_negative = 0
true_negative = 0

    for z in thresholds:
        print("Threshold => %f " % (z))
        fp = 0
        fn = 0
        tp = 0
        tn = 0
        for i in range(len(yt)):
            if( yt[i] == 0 and predictions[i] > z ):
                fp += 1
            elif( yt[i] == 1 and predictions[i] > z ):
                tp += 1
            elif( yt[i] == 1 and predictions[i] <= z ):
                fn += 1
            elif( yt[i] == 0 and predictions[i] <= z ):
                tn += 1
        
        if( (tp+fn) == 0):
            continue
        if( (tn+fp) == 0):
            continue
        TPR = fp / (fp + tn)
        #sens = tp / (tp + fn)
        #spec = tn / (tn + fp)
        FPR = tp / (tp + fn)
        Gscore = math.sqrt(TPR*(1-FPR))

        print("J Stat => %f " % (Gscore), flush=True)

        if( Gscore > best_Gscore ):
            best_Gscore = Gscore
            false_positive = fp
            false_negative = fn
            true_positive = tp
            true_negative = tn
            threshold = z

但是有没有更好的方法来最大化感官和规格?也许找到一种感觉和规格,例如

| sens - spec | < 0.05 and sens*spec > score_max

然后,一旦找到这个 score_max,您就可以在两者上运行较小的跳跃,例如 +- 0.2?还是有另一种方法可以找到灵敏度和特异性最大值?

1个回答

一般来说,不可能同时优化灵敏度和特异性,因为要找到灵敏度最大且特异性最大的阈值:

  • TP高、FN低时灵敏度高
  • TN 高而 FP 低时特异性高

但由于:

  • 当阈值增加时,更多的实例被预测为负,因此 TN 和 FN 增加,TP 和 FP 减少。
  • 当阈值降低时,更多的实例被预测为正,因此 TP 和 FP 增加,TN 和 FN 减少。

因此,一个人不可能同时拥有尽可能低的 FP 和尽可能低的 FN。

换句话说,最大敏感性是所有实例都被预测为阳性,而最大特异性是所有实例都被预测为阴性。显然两者都不兼容。

相反,只能优化两者的组合,类似于 F 分数,它是精度(与特异性相关)和召回率(灵敏度)的调和平均值。