mlebench/metrics.py (29 lines of code) (raw):

import numpy as np def average_precision_at_k(actual: set, predicted: list, k: int): """ Computes the average precision at k (AP@k). This function computes the average precision at k between a predicted ranking and a ground truth set. Args: actual : A set of elements that are to be predicted (order doesn't matter) predicted : A list of predicted elements (order does matter, most relevant go first) k : The maximum number of predicted elements Adapted from: https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/average_precision.py """ if len(predicted) > k: predicted = predicted[:k] score = 0.0 num_hits = 0.0 for i, p in enumerate(predicted): if p in actual and p not in predicted[:i]: num_hits += 1.0 score += num_hits / (i + 1.0) if not actual: return 0.0 return score / min(len(actual), k) def mean_average_precision_at_k(actual: list[set], predicted: list[list], k: int): """ Computes the MAP@k Args: actual : a list of sets of the elements that are to be predicted (order doesn't matter) predicted : a list of lists of predicted elements (order does matter, most relevant go first) k : The maximum number of predicted elements """ return np.mean([average_precision_at_k(a, p, k) for a, p, in zip(actual, predicted)]) def dice_coefficient( predicted_mask: np.ndarray, true_mask: np.ndarray, both_empty_value: float = np.nan ) -> float: """ Computes the Dice coefficient between two binary masks (can be multi-dimensional) Args: predicted_mask: A binary numpy array indicating where the segmentation is predicted true_mask: A binary numpy array indicating where the segmentation is both_empty_value: The value to return when both masks are empty """ assert ( predicted_mask.shape == true_mask.shape ), f"Predicted mask shape {predicted_mask.shape} does not match true mask shape {true_mask.shape}" # Check if both masks are empty if np.sum(predicted_mask) == 0 and np.sum(true_mask) == 0: return both_empty_value # Calculate intersection and union intersection = np.sum(predicted_mask * true_mask) union = np.sum(predicted_mask) + np.sum(true_mask) if union == 0: return both_empty_value # Calculate Dice coefficient dice_coeff = 2 * intersection / union return dice_coeff