An interviewer asks: "Your classifier gives scores between 0 and 1. Write a function that picks the threshold with the best F1, and return its precision and recall." A threshold, or cut, turns a score into a prediction: 1 when the score is at least the cut, 0 below it. The usual cut 0.5 is only a habit; the best one depends on the data.
The idea: try each distinct score as the cut, measure F1 there, and keep the best. Between two neighboring scores the predictions don't change, so no other cut can do better. np.unique(scores) gives back the distinct scores, sorted from small to large. scores >= cut gives back a True/False array, and .astype(int) turns it into 1s and 0s. The given precision_recall_f1(labels, predicted) gives back three numbers: precision, recall, and F1 = 2 × precision × recall / (precision + recall); when no prediction is right, it gives back three 0s.
For example, with the scores [0.9, 0.7, 0.4, 0.3, 0.2] and the labels [1, 0, 1, 1, 0], the cut 0.5 gets an F1 of only 0.4. Trying every score as the cut:
cut 0.2 → predicted [1 1 1 1 1] precision 0.6 recall 1.0 F1 0.75 cut 0.3 → predicted [1 1 1 1 0] precision 0.75 recall 1.0 F1 0.857 cut 0.4 → predicted [1 1 1 0 0] precision 0.667 recall 0.667 F1 0.667 cut 0.7 → predicted [1 1 0 0 0] precision 0.5 recall 0.333 F1 0.4 cut 0.9 → predicted [1 0 0 0 0] precision 1.0 recall 0.333 F1 0.5
The best cut there is 0.3. To find it in a loop, keep the best so far in a dict that starts with an F1 of -1, so the first cut always beats it, and replace it only when a cut's F1 is bigger. On a tie, the cut found first stays.
On the lesson's 11 scores, your code must print the lines below. The check then tries a perfect split (cut 0.8, F1 1.0) and a list where only the lowest score is a 1, and compares your answers with scikit-learn on 20 random score lists.
F1 at the usual 0.5 cut: 0.5 Best cut: 0.4 Precision: 0.75 Recall: 0.857 F1: 0.8
Your task: the scores, the labels, precision_recall_f1 and the printing are given. Fill best_threshold above its return best: start best with an F1 of -1, loop over the distinct scores as cuts, predict with each, measure, and keep the cut with the biggest F1 together with its precision and recall.
Assignment
Follow the Coding Tutorial to write best_threshold, one line per step.
Hint
Compare with >, not >=, against best["f1"], and store all four keys, "cut", "precision", "recall" and "f1", each time a cut wins: the printing reads every one of them.
Free plan: 30 tutor messages. PRO is unlimited.
