Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keras custom decision threshold for precision and recall

I'm doing a binary classification using Keras (with Tensorflow backend) and I've got about 76% precision and 70% recall. Now I want to try to play with decision threshold. As far as I know Keras uses decision threshold 0.5. Is there a way in Keras to use custom threshold for decision precision and recall?

Thank you for your time!

like image 394
nabroyan Avatar asked Mar 05 '17 08:03

nabroyan


People also ask

How does threshold affect precision and recall?

The higher the threshold, the higher the precision, but the lower the recall. Note that high precision is required when you use IBM® Content Classification to generate automatic responses (these should be as accurate as possible). The ideal threshold setting is the highest possible recall and precision rate.

How do you find the threshold from a precision recall curve?

Optimal Threshold for Precision-Recall Curve Recall is calculated as the ratio of the number of true positives divided by the sum of the true positives and the false negatives.

Does precision increase with threshold?

Definitely increase. Raising the classification threshold typically increases precision; however, precision is not guaranteed to increase monotonically as we raise the threshold.

How would you identify the best threshold for the F1 score for your classification model?

In it, we identified that when your classifier outputs calibrated probabilities (as they should for logistic regression) the optimal threshold is approximately 1/2 the F1 score that it achieves. This gives you some intuition. The optimal threshold will never be more than . 5.


1 Answers

create custom metrics like this :

Edited thanks to @Marcin : Create functions that returns the desired metrics with threshold_value as argument

def precision_threshold(threshold=0.5):
    def precision(y_true, y_pred):
        """Precision metric.
        Computes the precision over the whole batch using threshold_value.
        """
        threshold_value = threshold
        # Adaptation of the "round()" used before to get the predictions. Clipping to make sure that the predicted raw values are between 0 and 1.
        y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), threshold_value), K.floatx())
        # Compute the number of true positives. Rounding in prevention to make sure we have an integer.
        true_positives = K.round(K.sum(K.clip(y_true * y_pred, 0, 1)))
        # count the predicted positives
        predicted_positives = K.sum(y_pred)
        # Get the precision ratio
        precision_ratio = true_positives / (predicted_positives + K.epsilon())
        return precision_ratio
    return precision

def recall_threshold(threshold = 0.5):
    def recall(y_true, y_pred):
        """Recall metric.
        Computes the recall over the whole batch using threshold_value.
        """
        threshold_value = threshold
        # Adaptation of the "round()" used before to get the predictions. Clipping to make sure that the predicted raw values are between 0 and 1.
        y_pred = K.cast(K.greater(K.clip(y_pred, 0, 1), threshold_value), K.floatx())
        # Compute the number of true positives. Rounding in prevention to make sure we have an integer.
        true_positives = K.round(K.sum(K.clip(y_true * y_pred, 0, 1)))
        # Compute the number of positive targets.
        possible_positives = K.sum(K.clip(y_true, 0, 1))
        recall_ratio = true_positives / (possible_positives + K.epsilon())
        return recall_ratio
    return recall

now you can use them in

model.compile(..., metrics = [precision_threshold(0.1), precision_threshold(0.2),precision_threshold(0.8), recall_threshold(0.2,...)])

I hope this helps :)

like image 165
Nassim Ben Avatar answered Sep 21 '22 16:09

Nassim Ben