def precision(relevant_ranks: list) -> list: """ A function to return the precision as a function of rank. The function must be passed a list of the rank positions of relevant documents. """ n = max(relevant_ranks) results = [0.]*n n_retrieved = 0 n_relevant = 0 for i in range(n): rank = i + 1 if rank in relevant_ranks: n_relevant += 1 n_retrieved += 1 results[i] = n_relevant/n_retrieved return results def recall(relevant_ranks: list) -> list: """ A function to return the recall as a function of rank. The function must be passed a list of the rank positions of relevant documents. """ n = max(relevant_ranks) results = [0.]*n total_relevant = len(relevant_ranks) n_relevant = 0 for i in range(n): rank = i + 1 if rank in relevant_ranks: n_relevant += 1 results[i] = n_relevant/total_relevant return results def interpolate_precision(recall: list, precision: list) -> list: """ A function to interpolate precision values. The function returns a tuple of the interpolated recall and precision. """ if len(recall) == 0 or len(precision) == 0: return ([], []) # Interpolate to the right. n = len(precision) int_precision = [0.] * n for i in range(n): int_precision[i] = max(precision[i:]) # Interpolate back to recall = 0. int_recall = recall.copy() if int_recall[0] != 0: int_recall = [0] + int_recall int_precision = [int_precision[0]] + int_precision return (int_recall, int_precision) def average_precision(relevant_ranks: list, precision: list) -> list: """ A function to calculate the average precision at each rank. """ n = len(precision) ranks = list(range(1, n+1)) results = [0.] * n n_relevant = [0] * n for i in range(n): if i > 0: results[i] += results[i - 1] n_relevant[i] += n_relevant[i - 1] if ranks[i] in relevant_ranks: results[i] += precision[i] n_relevant[i] += 1 for i in range(n): results[i] /= n_relevant[i] return results