import numpy as np def compute_average_precision(precision, recall): """ It computes average precision based on the definition of Pascal Competition. It computes the under curve area of precision and recall. Recall follows the normal definition. Precision is a variant. pascal_precision[i] = typical_precision[i:].max() """ # identical but faster version of new_precision[i] = old_precision[i:].max() precision = np.concatenate([[0.0], precision, [0.0]]) for i in range(len(precision) - 1, 0, -1): precision[i - 1] = np.maximum(precision[i - 1], precision[i]) # find the index where the value changes recall = np.concatenate([[0.0], recall, [1.0]]) changing_points = np.where(recall[1:] != recall[:-1])[0] # compute under curve area areas = (recall[changing_points + 1] - recall[changing_points]) * precision[changing_points + 1] return areas.sum() def compute_voc2007_average_precision(precision, recall): ap = 0. for t in np.arange(0., 1.1, 0.1): if np.sum(recall >= t) == 0: p = 0 else: p = np.max(precision[recall >= t]) ap = ap + p / 11. return ap