Problem 358419 · easy · Level 03 Linear Management & Searching

Did the Camera Really See a Hedgehog?

precision · recall · F1 score · true and false positives

A garden camera trap sends a message whenever its recogniser thinks it saw a hedgehog. Its owner has checked a batch of photos: actual[i] is what is really in photo i and predicted[i] is what the recogniser said. Only one label matters here, the positive one; every other label counts as "not positive".

Write precision_recall_f1(actual, predicted, positive) that returns a tuple of three floats:

  • precision: of the photos predicted positive, the share that really are positive (0.0 if nothing was predicted positive);
  • recall: of the photos that really are positive, the share predicted positive (0.0 if there are none);
  • F1: 2 · precision · recall / (precision + recall), or 0.0 if both are 0.

The setup provides camera_trap(n, seed, eager=0.5), which returns (actual, predicted) for n random photos with labels "hedgehog", "fox", "cat" and "empty"; a larger eager makes the recogniser say "hedgehog" more readily.

Examples

Input:  actual    = ["hedgehog", "empty", "hedgehog", "fox", "hedgehog", "empty"]
        predicted = ["hedgehog", "hedgehog", "empty", "fox", "hedgehog", "empty"]
        positive = "hedgehog"
Output: (0.6666666666666666, 0.6666666666666666, 0.6666666666666666)
Explanation: 3 photos are called "hedgehog" and 2 of them are right (precision 2/3);
3 photos really show a hedgehog and 2 are found (recall 2/3).

Input:  actual = ["hedgehog", "cat"], predicted = ["cat", "cat"], positive = "hedgehog"
Output: (0.0, 0.0, 0.0)
Explanation: nothing was called a hedgehog, so precision is 0.0 by the rule above.

Constraints

  • 0 <= len(actual) == len(predicted) <= 10**5
  • floats are compared with a tolerance of 1e-6

Goals

  • Count true positives, false positives and false negatives for one class
  • Compute precision, recall and their harmonic mean, the F1 score
  • Handle the cases where a ratio would divide by zero
Starting Python…