PY-70

Calculate Per-Label Measures from Counts

  • Medium
  • Evaluation Arrays
  • Python

Task

Write calculate_per_label_measures(counts, labels) for a square count table. counts[i, j] records how many aligned items had label labels[i] in the first column of a comparison and labels[j] in the second column. The table is a non-empty square integer NumPy array with no negative entries. labels is a non-empty sequence of unique values whose length is the table size.

Return one dictionary with labels as a tuple, measures as a list of records, macro, micro, and total. Keep the records in the supplied label order. A per-label record has these fields:

label, true_positive, false_positive, false_negative, support,
precision, recall, f1

For label i, derive the counts from the table:

true_positive  = counts[i, i]
false_positive = column_total[i] - true_positive
false_negative = row_total[i] - true_positive
support       = row_total[i]

Then calculate the three fractions. A fraction with a zero denominator is exactly 0.0:

precision = true_positive / (true_positive + false_positive)
recall    = true_positive / (true_positive + false_negative)
f1        = 2 * precision * recall / (precision + recall)

macro contains the arithmetic mean of the per-label precision, recall, and f1 values, including labels with zero support. micro first sums all true-positive, false-positive, and false-negative values, then applies the same three formulas to those sums. Thus a zero denominator still produces 0.0. total is the sum of every cell in counts.

If the input contract is invalid, raise ValueError with "invalid count table". Do not change the array or label sequence.

Example

With labels ("cat", "dog") and

counts = np.array([[2, 1], [0, 0]])

the cat record has true_positive=2, false_positive=0, false_negative=1, precision=1.0, recall=2/3, and f1=0.8. The dog record has zero support, so all three of its fractions are 0.0 even though its precision denominator is also zero.

Your implementation

Edit solution.py and keep this function signature:

You may import NumPy as np. Return ordinary Python numbers inside the records and aggregate dictionaries. Do not modify an input, print, or ask for input.