Diff of /python/evaluation_AAMI.py [000000] .. [4d064f]

Switch to unified view

a b/python/evaluation_AAMI.py
1
#!/usr/bin/env python
2
3
"""
4
train_SVM.py
5
    
6
VARPA, University of Coruna
7
Mondejar Guerra, Victor M.
8
26 Oct 2017
9
"""
10
11
from sklearn import metrics
12
import numpy as np
13
14
class performance_measures:
15
    def __init__(self, n):
16
        self.n_classes          = n
17
        self.confusion_matrix   = np.empty([])
18
        self.Recall             = np.empty(n)
19
        self.Precision          = np.empty(n)
20
        self.Specificity        = np.empty(n)
21
        self.Acc                = np.empty(n)
22
        self.F_measure          = np.empty(n)
23
24
        self.gmean_se          = 0.0
25
        self.gmean_p           = 0.0
26
27
        self.Overall_Acc        = 0.0
28
        self.kappa              = 0.0
29
        self.Ij                 = 0.0
30
        self.Ijk                = 0.0
31
32
33
34
# Compute Cohen' kappa from a confussion matrix
35
# Kappa value:
36
#    < 0.20  Poor
37
# 0.21-0.40  Fair
38
# 0.41-0.60  Moderate
39
# 0.61-0.80  Good
40
# 0.81-1.00  Very good
41
def compute_cohen_kappa(confusion_matrix):
42
    prob_expectedA = np.empty(len(confusion_matrix))
43
    prob_expectedB = np.empty(len(confusion_matrix))
44
    prob_observed = 0
45
    
46
    for n in range(0, len(confusion_matrix)):
47
        prob_expectedA[n] = sum(confusion_matrix[n,:]) / sum(sum(confusion_matrix))
48
        prob_expectedB[n] = sum(confusion_matrix[:,n]) / sum(sum(confusion_matrix))
49
    
50
        prob_observed = prob_observed + confusion_matrix[n][n]
51
52
    prob_expected = np.dot(prob_expectedA, prob_expectedB)
53
    prob_observed = prob_observed / sum(sum(confusion_matrix))  
54
55
    kappa = (prob_observed - prob_expected) / (1 - prob_expected)
56
57
    return kappa, prob_observed, prob_expected
58
59
# Compute the performance measures following the AAMI recommendations.
60
# Using sensivity (recall), specificity (precision) and accuracy 
61
# for each class: (N, SVEB, VEB, F)
62
def compute_AAMI_performance_measures(predictions, gt_labels):
63
    n_classes = 4 #5
64
    pf_ms = performance_measures(n_classes)
65
66
    # TODO If conf_mat no llega a clases 4 por gt_labels o predictions...
67
    # hacer algo para que no falle el codigo...
68
    # NOTE: added labels=[0,1,2,3])...
69
70
    # Confussion matrix
71
    conf_mat = metrics.confusion_matrix(gt_labels, predictions, labels=[0,1,2,3])
72
    conf_mat = conf_mat.astype(float)
73
    pf_ms.confusion_matrix = conf_mat
74
75
    # Overall Acc
76
    pf_ms.Overall_Acc = metrics.accuracy_score(gt_labels, predictions)
77
78
    # AAMI: Sens, Spec, Acc 
79
    # N: 0, S: 1, V: 2, F: 3                        # (Q: 4) not used
80
    for i in range(0, n_classes):
81
        TP = conf_mat[i,i]
82
        FP = sum(conf_mat[:,i]) - conf_mat[i,i]
83
        TN = sum(sum(conf_mat)) - sum(conf_mat[i,:]) - sum(conf_mat[:,i]) + conf_mat[i,i]
84
        FN = sum(conf_mat[i,:]) - conf_mat[i,i]
85
86
        if i == 2: # V 
87
            # Exceptions for AAMI recomendations:
88
            # 1 do not reward or penalize a classifier for the classification of (F) as (V)
89
            FP = FP - conf_mat[i][3]
90
        
91
        pf_ms.Recall[i]       = TP / (TP + FN)
92
        pf_ms.Precision[i]    = TP / (TP + FP)
93
        pf_ms.Specificity[i]  = TN / (TN + FP); # 1-FPR
94
        pf_ms.Acc[i]          = (TP + TN) / (TP + TN + FP + FN)
95
96
        if TP == 0:
97
            pf_ms.F_measure[i] = 0.0
98
        else:
99
            pf_ms.F_measure[i] = 2 * (pf_ms.Precision[i] * pf_ms.Recall[i] )/ (pf_ms.Precision[i] + pf_ms.Recall[i])
100
101
    # Compute Cohen's Kappa
102
    pf_ms.kappa, prob_obsv, prob_expect = compute_cohen_kappa(conf_mat)
103
104
    # Compute Index-j   recall_S + recall_V + precision_S + precision_V
105
    pf_ms.Ij = pf_ms.Recall[1] + pf_ms.Recall[2] + pf_ms.Precision[1] + pf_ms.Precision[2]
106
107
    # Compute Index-jk
108
    w1 = 0.5
109
    w2 = 0.125
110
    pf_ms.Ijk = w1 * pf_ms.kappa + w2 * pf_ms.Ij
111
112
    return pf_ms
113
114
115
# Export to filename.txt file the performance measure score
116
def write_AAMI_results(performance_measures, filename):
117
118
    f = open(filename, "w") 
119
120
    f.write("Ijk: " + str(format(performance_measures.Ijk, '.4f')) + "\n")
121
    f.write("Ij: " + str(format(performance_measures.Ij, '.4f'))+ "\n")
122
    f.write("Cohen's Kappa: " + str(format(performance_measures.kappa, '.4f'))+ "\n\n")
123
124
    # Conf matrix
125
    f.write("Confusion Matrix:"+ "\n\n")
126
    f.write("\n".join(str(elem) for elem in performance_measures.confusion_matrix.astype(int))+ "\n\n")
127
128
    f.write("Overall ACC: " + str(format(performance_measures.Overall_Acc, '.4f'))+ "\n\n")
129
130
    f.write("mean Acc: " + str(format(np.average(performance_measures.Acc[:]), '.4f'))+ "\n")
131
    f.write("mean Recall: " + str(format(np.average(performance_measures.Recall[:]), '.4f'))+ "\n")
132
    f.write("mean Precision: " + str(format(np.average(performance_measures.Precision[:]), '.4f'))+ "\n")
133
  
134
135
    f.write("N:"+ "\n\n")
136
    f.write("Sens: " + str(format(performance_measures.Recall[0], '.4f'))+ "\n")
137
    f.write("Prec: " + str(format(performance_measures.Precision[0], '.4f'))+ "\n")
138
    f.write("Acc: " + str(format(performance_measures.Acc[0], '.4f'))+ "\n")
139
140
    f.write("SVEB:"+ "\n\n")
141
    f.write("Sens: " + str(format(performance_measures.Recall[1], '.4f'))+ "\n")
142
    f.write("Prec: " + str(format(performance_measures.Precision[1], '.4f'))+ "\n")
143
    f.write("Acc: " + str(format(performance_measures.Acc[1], '.4f'))+ "\n")
144
145
    f.write("VEB:"+ "\n\n")
146
    f.write("Sens: " + str(format(performance_measures.Recall[2], '.4f'))+ "\n")
147
    f.write("Prec: " + str(format(performance_measures.Precision[2], '.4f'))+ "\n")
148
    f.write("Acc: " + str(format(performance_measures.Acc[2], '.4f'))+ "\n")
149
150
    f.write("F:"+ "\n\n")
151
    f.write("Sens: " + str(format(performance_measures.Recall[3], '.4f'))+ "\n")
152
    f.write("Prec: " + str(format(performance_measures.Precision[3], '.4f'))+ "\n")
153
    f.write("Acc: " + str(format(performance_measures.Acc[3], '.4f'))+ "\n")
154
155
156
    f.close()