私は、偽陰性をできるだけ少なくしようとしている医療データセットに取り組んでいます。 「実際に病気がないときに病気になる」という予測は私には問題ありませんが、「実際に病気がないときに病気がない」という予測はそうではありません。つまり、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はかなり高くなりました。 FNを非常に低く保ちながら、FPを可能な限り削減しようとしています。
Keras
を使用してカスタム損失関数を作成するのに苦労しています。これは、偽陰性にペナルティを科すのに役立ちます。助けてくれてありがとう。
私たちが取り組んでいる概念を簡単に紹介します。
allからpositive、どのように私たちのモデルは多くの人がポジティブであると予測しましたか?
ポジティブだったすべて=
私たちのモデルが言ったことは肯定的でした=
リコールはFNに反比例するため、リコールを改善するとFNが減少します。
allからnegative、どのように多くのモデルがネガティブと予測しましたか?
否定的だったすべて=
私たちのモデルが言ったことは否定的でした=
リコールはFPに反比例するため、リコールを改善するとFPが減少します。
次の検索、または実行する分類関連のアクティビティでは、これらを知っていると、コミュニケーションと理解がさらに向上します。
そう。あなたがすでに理解しているように、これらの2つの概念は反対です。これは、一方を増やすともう一方が減少する可能性が高いことを意味します。
リコール時にpriorityが必要ですが、特異性をあまり緩めたくないので、これらと属性の重みの両方を組み合わせることができます。 この回答 で明確に説明されていることに従う:
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に等しくする必要があります。