forked from snap-stanford/mars
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevaluation.py
71 lines (55 loc) · 2.29 KB
/
evaluation.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
'''
Created on Jan 21, 2020
@author: maria
'''
import numpy as np
from collections import defaultdict
import sklearn.metrics as metrics
from sklearn.utils.linear_assignment_ import linear_assignment
def evaluate_predictions(y_true, y_pred, scoring={'accuracy','precision','recall','nmi','adj_rand','f1_score','adj_mi'}):
"""
Evaluation of predictions given true labels.
y_true: true cluster labels
y_pred: predicted cluster labels
"""
scores = defaultdict(list)
y_true, y_pred = hungarian_match(y_true, y_pred)
set_scores(scores, y_true, y_pred, scoring)
return scores
def set_scores(scores, y_true, y_pred, scoring):
labels=list(set(y_true))
for metric in scoring:
if metric=='accuracy':
scores[metric] = metrics.accuracy_score(y_true, y_pred)
elif metric=='precision':
scores[metric] = metrics.precision_score(y_true, y_pred, labels, average='macro')
elif metric=='recall':
scores[metric] = metrics.recall_score(y_true, y_pred, labels, average='macro')
elif metric=='f1_score':
scores[metric] = metrics.f1_score(y_true, y_pred, labels, average='macro')
elif metric=='nmi':
scores[metric] = metrics.normalized_mutual_info_score(y_true, y_pred)
elif metric=='adj_mi':
scores[metric] = metrics.adjusted_mutual_info_score(y_true, y_pred)
elif metric=='adj_rand':
scores[metric] = metrics.adjusted_rand_score(y_true, y_pred)
def hungarian_match(self, y_true, y_pred):
"""Matches predicted labels to original using hungarian algorithm."""
y_true = self.adjust_range(y_true)
y_pred = self.adjust_range(y_pred)
D = max(y_pred.max(), y_true.max()) + 1
w = np.zeros((D, D), dtype=np.int64)
# Confusion matrix.
for i in range(y_pred.size):
w[y_pred[i], y_true[i]] += 1
ind = linear_assignment(-w)
d = {i:j for i, j in ind}
y_pred = np.array([d[v] for v in y_pred])
return y_true, y_pred
def adjust_range(self, y):
"""Assures that the range of indices if from 0 to n-1."""
y = np.array(y, dtype=np.int64)
val_set = set(y)
mapping = {val:i for i,val in enumerate(val_set)}
y = np.array([mapping[val] for val in y], dtype=np.int64)
return y