import math def recall_at_k(actual, predicted, topk): sum_recall = 0.0 num_users = len(predicted) true_users = 0 for i in range(num_users): act_set = set([actual[i]]) pred_set = set(predicted[i][:topk]) if len(act_set) != 0: sum_recall += len(act_set & pred_set) / float(len(act_set)) true_users += 1 return sum_recall / true_users def ndcg_k(actual, predicted, topk): res = 0 for user_id in range(len(actual)): k = min(topk, len([actual[user_id]])) idcg = idcg_k(k) dcg_k = sum([int(predicted[user_id][j] in set([actual[user_id]])) / math.log(j+2, 2) for j in range(topk)]) res += dcg_k / idcg return res / float(len(actual)) # Calculates the ideal discounted cumulative gain at k def idcg_k(k): res = sum([1.0/math.log(i+2, 2) for i in range(k)]) if not res: return 1.0 else: return res