-
Notifications
You must be signed in to change notification settings - Fork 0
/
analyse.py
262 lines (237 loc) · 9.65 KB
/
analyse.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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# -*- coding: utf-8 -*-
import numpy as np
from sklearn.metrics import confusion_matrix, roc_curve
from matplotlib import pyplot as plt
import matplotlib.gridspec as gridspec
class Analyse:
def __init__(self, verite_terrain, resultats, probabilites):
"""
Classe servant à faire l'analyse des résultats de
l'entraînement d'un modèle, basé sur des métriques
telles que le rappel, la justesse, la précision, etc,
ainsi que sur une courbe ROC.
Prend en entrée la vérité terrain (donc les étiquettes
de classe), les résultats (donc les prédictions du modèle)
et les probabilités des résultats, tels que fournis
préalablement par la méthode confiance_test de la classe
Classifieur.
"""
self.verite_terrain = verite_terrain
self.resultats = resultats
self.probabilites = probabilites
self.vp = 0
self.vn = 0
self.fp = 0
self.fn = 0
self.tvp = None
self.tfp = None
self.metriques = np.zeros(5)
def calculer_comptes(self, est_ech_poids=False, *args):
"""
Cette méthode compte le nombre de vrais positifs, de
faux positifs, de vrais négatifs et de faux négatifs.
Elle doit être appelée avant de pouvoir utiliser les prochaines
méthodes (autre que celles concernant la courbe ROC).
"""
# Cas avec poids variables
if(est_ech_poids):
matrice_confusion = confusion_matrix(self.verite_terrain,
self.resultats, sample_weight=args[0])
# Cas sans poids variables
else:
matrice_confusion = confusion_matrix(self.verite_terrain,
self.resultats)
self.vn, self.fp, self.fn, self.vp = matrice_confusion.ravel()
def afficher_comptes(self):
"""
Cette méthode sert à afficher à l'écran les résultats
de la méthode calculer_comptes.
"""
print("Vrais positifs : ", self.vp)
print("Faux positifs : ", self.fp)
print("Vrais négatifs : ", self.vn)
print("Faux négatifs : ", self.fn)
def calculer_rappel(self):
"""
Cette méthode calcule le rappel.
"""
return(self.vp / (self.fn + self.vp))
def calculer_justesse(self):
"""
Cette méthode calcule la justesse.
"""
return((self.vp + self.vn) / (self.vp + self.vn + self.fp + self.fn))
def calculer_precision(self):
"""
Cette méthode calcule la précision.
"""
return(self.vp / (self.vp + self.fp))
def calculer_specificite(self):
"""
Cette méthode calcule la spécificité.
"""
return(self.vn / (self.fp + self.vn))
def calculer_mesure_f(self):
"""
Cette méthode calcule la mesure-f.
"""
rappel = self.calculer_rappel()
precision = self.calculer_precision()
return((2 * rappel * precision) / (rappel + precision))
def calculer_metriques(self):
"""
Cette méthode sert à calculer les différentes
métriques en utilisant les méthodes précédentes.
"""
self.metriques[0] = self.calculer_rappel()
self.metriques[1] = self.calculer_justesse()
self.metriques[2] = self.calculer_precision()
self.metriques[3] = self.calculer_specificite()
self.metriques[4] = self.calculer_mesure_f()
def afficher_metriques(self):
"""
Cette méthode sert à afficher les résultats de
la méthode calculer_metriques.
"""
print("Rappel = ", self.metriques[0])
print("Justesse = ", self.metriques[1])
print("Précision = ", self.metriques[2])
print("Spécificité = ", self.metriques[3])
print("Mesure-f = ", self.metriques[4])
def calculer_courbe_roc(self, est_ech_poids=False, *args):
"""
Cette méthode calcule le nécessaire pour afficher
une courbe ROC.
"""
# Cas avec poids variables
if(est_ech_poids):
self.tfp, self.tvp, seuil = roc_curve(self.verite_terrain,
self.probabilites,
sample_weight=args[0],
drop_intermediate=False)
# Cas sans poids variables
else:
self.tfp, self.tvp, seuil = roc_curve(self.verite_terrain,
self.probabilites,
drop_intermediate=False)
def afficher_courbe_roc(self):
"""
Cette méthode sert à afficher le résultat de la méthode
calculer_courbe_roc.
"""
graph_init()
plt.figure()
# plt.title("Courbe ROC")
plt.xlabel("TFP")
plt.ylabel("TVP")
plt.plot(self.tfp, self.tvp, "b-")
plt.show()
class Analyse_multiple:
def __init__(self, repetitions):
"""
Classe servant à faire l'analyse des résultats de
l'entraînement d'un modèle, à la suite de plusieurs
répétitions. Elle sert à compléter la classe Analyse
en calculant les moyennes des métriques et en affichant
l'évolution de celles-ci au cours des répétitions.
Prend en entrée le nombre de répétitions choisi.
"""
self.repetitions = repetitions
self.erreurs = np.ndarray((repetitions, 2))
self.metriques = np.ndarray((repetitions, 5))
self.erreurs_moy = np.array([0, 0])
self.metriques_moy = np.array([0, 0, 0, 0, 0])
self.rep_courante = 0
def ajouter_erreurs(self, erreur_ent, erreur_test):
"""
Cette méthode ajoute les erreurs d'une répétition au
tableau des erreurs.
"""
self.erreurs[self.rep_courante] = [erreur_ent, erreur_test]
def ajouter_metriques(self, metriques):
"""
Cette méthode ajoute les métriques d'une répétition
au tableau des métriques.
"""
self.metriques[self.rep_courante] = metriques
def calculer_moyennes(self):
"""
Cette méthode calculer les moyennes des erreurs
et des métriques, idéalement à la fin des répétitions
"""
self.erreurs_moy = np.mean(self.erreurs, axis=0)
self.metriques_moy = np.mean(self.metriques, axis=0)
def augmenter_rep_courante(self):
"""
Cette méthode sert à mettre à jour l'itérateur
self.rep_courante pour savoir à quelle répétition
le code est rendu.
"""
self.rep_courante += 1
def afficher_moyennes(self):
"""
Cette méthode sert à afficher au terminal
toutes les moyennes calculées précédemment.
"""
print("Erreur d'entrainement moyenne = ", self.erreurs_moy[0], '%')
print("Erreur de test moyenne = ", self.erreurs_moy[1], '%')
print("Rappel moyen = ", self.metriques_moy[0])
print("Justesse moyenne = ", self.metriques_moy[1])
print("Précision moyenne = ", self.metriques_moy[2])
print("Spécificité moyenne = ", self.metriques_moy[3])
print("Mesure-f moyenne = ", self.metriques_moy[4])
def afficher_graphique(self):
"""
Cette méthode sert à afficher sous forme de graphique
les résultats compilés au fil des répétitions.
"""
rep = np.arange(1, self.repetitions + 1, 1)
graph_init()
fig = plt.figure()
widths = [2]
heights = [1, 1]
gs = gridspec.GridSpec(2, 1, figure=fig, width_ratios=widths,
height_ratios=heights)
ax = fig.add_subplot(gs[0, 0])
ax.plot(rep, 100 - self.erreurs[:, 0], "bs-", label="Entrainement")
ax.plot(rep, 100 - self.erreurs[:, 1], "gs-", label="Test")
ax.axhline(100 - self.erreurs_moy[0], color="b",
linestyle="--", alpha=0.4, linewidth=1.5)
ax.axhline(100 - self.erreurs_moy[1], color="g",
linestyle="--", alpha=0.4, linewidth=1.5)
plt.ylabel("Justesse en %")
plt.legend(loc=1)
plt.xticks(rep)
ax = fig.add_subplot(gs[1, 0])
ax.plot(rep, self.metriques[:, 0] * 100, "ro-", label="Rappel")
# plt.plot(rep, self.metriques[:, 1] * 100, "o-", label="Justesse")
ax.plot(rep, self.metriques[:, 2] * 100, "co-", label="Précision")
ax.plot(rep, self.metriques[:, 3] * 100, "yo-", label="Spécificité")
# plt.plot(rep, self.metriques[:, 4] * 100, "o-", label="Mesure-f")
plt.ylabel("Métriques en %")
plt.xlabel("# de répétition")
plt.xticks(rep)
plt.legend(loc=1)
plt.tight_layout()
plt.show()
def graph_init():
"""
Cette méthode à part sert à initialiser les
paramètres d'un graphique.
"""
plt.style.use('seaborn-notebook')
plt.rcParams['axes.grid'] = True
plt.rcParams['grid.color'] = "darkgrey"
plt.rcParams['grid.linewidth'] = 1
plt.rcParams['grid.linestyle'] = "-"
plt.rcParams['grid.alpha'] = "0.5"
plt.rcParams['figure.figsize'] = (12.0, 7.0)
plt.rcParams['font.size'] = 19
plt.rcParams['axes.labelsize'] = plt.rcParams['font.size']
plt.rcParams['axes.titlesize'] = 1 * plt.rcParams['font.size']
plt.rcParams['legend.fontsize'] = plt.rcParams['font.size']
plt.rcParams['xtick.labelsize'] = 0.9 * plt.rcParams['font.size']
plt.rcParams['ytick.labelsize'] = 0.9 * plt.rcParams['font.size']
plt.rcParams['axes.linewidth'] = 1
plt.rcParams['lines.linewidth'] = 2
plt.rcParams['lines.markersize'] = 8