-
Notifications
You must be signed in to change notification settings - Fork 0
/
Evaluation_Metrics.py
103 lines (76 loc) · 2.88 KB
/
Evaluation_Metrics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import math
from sklearn.metrics import roc_auc_score
class Evaluation_Metrics():
def __init__(self) -> None:
pass
def mean_average_precision(self, actual, recommended):
if len(actual) != len(recommended):
raise ValueError("Length of actual and predicted lists must be the same.")
mean_ap = 0.0
num_users = len(actual)
tot_users = 0
for i in range(num_users):
ap = 0.0 # Average Precision for current user
if len(actual[i]) == 0:
continue
tot_users += 1
num_correct_predictions = 0
precision_at_k = 0.0
for j in range(len(recommended[i])):
if recommended[i][j] in actual[i]:
num_correct_predictions += 1
precision_at_k += num_correct_predictions / (j + 1)
if num_correct_predictions > 0:
ap = precision_at_k / min(len(actual[i]), len(recommended[i]))
mean_ap += ap
mean_ap /= tot_users
return mean_ap
def precision_recall(self,actual, recommended):
total_precision = 0
total_recall = 0
for idx in range(len(recommended)):
tp=0
fp=0
recs = recommended[idx]
targets = actual[idx]
for item in recs:
if item in targets:
tp+=1
else:
fp+=1
fn = len(targets) - tp
total_precision += tp / (tp + fp)
total_recall += tp / (tp + fn)
return total_precision/len(recommended), total_recall/len(recommended)
def ndcg(self,actual, recommended):
gains = []
for idx in range(len(recommended)):
liked_set = set(actual[idx])
rec_items = recommended[idx]
user_gains = [1 if item in liked_set else 0 for item in rec_items]
gains.append(user_gains)
dcg = 0
for user in gains:
for idx in range(len(user)):
rank = idx + 1
gain = user[idx]
x = math.log2(rank + 1)
dcg += gain/x
idcg = 0
ideal = []
for user in range(len(actual)):
temp_ideal = []
for item in actual[user]:
temp_ideal.append(1)
if len(temp_ideal) > len(recommended[user]):
missing = len(temp_ideal) - len(recommended[user])
temp_ideal.extend([0]*missing)
ideal.append(temp_ideal)
for user in ideal:
for idx in range(len(user)):
rank = idx + 1
gain = user[idx]
x = math.log2(rank + 1)
idcg += gain/x
ndcg = dcg/idcg
return ndcg