Я кратко представлю концепции, которые мы пытаемся решить.
Напомним
Из всех , которые были положительными , сколько наша модель предсказала как положительные?
Все, что было положительным =
То, что наша модель сказала, было положительным =
Поскольку отзыв обратно пропорционален FN, улучшениеоно уменьшает FN.
Специфичность
Из всех , которые были отрицательными , сколько наша модель предсказала как отрицательную?
Все, что было отрицательным =
То, что наша модель сказала, было отрицательным =
Поскольку отзыв является обратно пропорциональнымдо FP, улучшая его, уменьшает FP.
Во время следующих поисков или любой другой деятельности, связанной с классификацией, которую вы выполняете, зная, что это даст вам дополнительное преимущество в общении и понимании.
Решение
Итак.Эти две концепции, как вы уже поняли, являются противоположностями.Это означает, что увеличение одного может уменьшить другое .
Так как вы хотите приоритет при отзыве, но не хотите терять слишком много специфичности, выможно комбинировать как эти, так и веса атрибутов.После того, что ясно объяснено в этом ответе :
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.