-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlearning_module.py
200 lines (147 loc) · 8.24 KB
/
learning_module.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
# -*- coding: utf-8 -*-
'''
Módulo de aprendizaje
Contiene todas las funcionalidades asociadas al aprendizaje del sistema. Esto incluye:
-Análisis de los criterios utilizados.
-Autoconfiguración del sistema.
'''
class Learning_Module():
'''
MÉTODOS PRINCIPALES
'''
'''
Analiza los resultados obtenidos y los criterios utilizados. A partir de esto, devuelve una nueva colección
de criterios con los subcriterios más relevantes.
Input:
-criteria: Dict. Colección de criterios utilizados.
-expected: List. Lista con los resultados esperados. Cada elemento de la lista es una lista con los resultados esperados para cada criterio evaluado.
-execution_results: List. Lista con los resultados obtenidos. Cada elemento de la lista es una lista con los resultados para cada criterio. Para cada criterio, almacena:
-porcentaje de criterios encontrados.
-resultado con la configuración actual OK/KO (no se utiliza en el filtrado)
-Lista con los subcriterios encontrados
Output:
-Dict. Nueva colección de criterios con los subcriterios filtrados.
'''
def analyze_kw(self,
criteria=dict(),
expected=list(),
execution_results=list()
):
results=self._get_criteria_percentages(criteria, expected, execution_results) #Calculamos el porcentaje de instancias positivas y negativas en las que aparece cada subcriterio de cada criterio.
return self._filter_using_rules(criteria, results) #Extraemos los subcriterios relevantes (obviamos los que no pasan los filtros). Si, después del filtro, algún criterio se queda sin subcriterios, reestablecemos los originales.
'''
Analiza los resultados obtenidos y los esperados. En base a estos, obtiene el kw_threshold_value que genera una mayor precisión (accuracy).
Input:
-results: List. Lista con los resultados obtenidos en la ejecución previa. Cada elemento de la lista consistirá en una tupla con los resultados asociados a cada criterio.
-expected_results: List. Lista con los resultados esperados. Cada elemento de la lista consistirá en una tupla con las evaluaciones asociadas a cada criterio de cada documento.
'''
def get_best_kw_threshold_values(self,
results=list(),
expected_results=list()
):
num_crit=len(expected_results[0]) #Obtenemos el número de criterios a tratar.
num_docs=len(results)
percentages, expected= self._prepare_best_kw_value_analysis(results, expected_results, num_crit)
thresholds=dict()
for crit in range(num_crit):
#Para cada criterio, vemos el valor de kw_treshold value que da una precisión mayor.
best_value, best_acc=0, 0
#Probamos valores entre 0 y 100.
for value in range(101):
acc=0
for pos in range(num_docs):
percentage=percentages[crit][pos]*100
expected_value=expected[crit][pos]
#Cálculos asociados a la accuracy
if percentage>=value and expected_value=='OK':
acc+=1
elif percentage < value and expected_value=='KO':
acc+=1
#Asociados a la accuracy
if acc >= best_acc:
best_value=value
best_acc=acc
thresholds[crit]=best_value/100
return thresholds
'''
MÉTODOS INTERNOS
'''
#Prepara las estructuras que se utilizarán para almacenar los resultados en el análisis de los criterios.
def _prepare_kw_analysis(self, criteria):
#Diccionario que almacenará cuantas muestras positivas y negativas hay que de cada criterio.
pn_samples=dict() #positive/negative samples.
for x in list(criteria.keys()):
pn_samples[x]=dict()
pn_samples[x]['OK']=0
pn_samples[x]['KO']=0
#Creamos un diccionario que almacenará los resultados.
results=dict()
results['OK']=dict()
results['KO']=dict()
for x,y in criteria.items():
results['OK'][x]=dict()
results['KO'][x]=dict()
for z in y:
results['OK'][x][z]=0
results['KO'][x][z]=0
return pn_samples, results
#Obtiene una nueva colección de criterios filtrando los criterios que no cumplen las reglas especificadas en la documentación.
def _filter_using_rules(self, criteria, results):
new_criteria= dict()
ok, ko =results['OK'], results['KO']
for crit in list(ok.keys()): #num crit
new_criteria[crit]=list()
for subcrit in list(results['OK'][crit].keys()):
pos=ok[crit][subcrit]
neg=ko[crit][subcrit]
if (pos - neg >= 0.3 ) and neg <= 0.4 or (neg==0 and pos >0):
new_criteria[crit].append(subcrit)
#Si algún criterio no tiene ningún elemento, pone los que había originalmente
for crit in list(new_criteria.keys()):
if len(new_criteria[crit])==0:
new_criteria[crit]= criteria[crit]
return new_criteria
#Dados los resultados esperados y los obtenidos, devuelve el porcentaje de aparición de cada subcriterio tanto para instancias positivas (OK) como instancias negativas (KO).
def _get_criteria_percentages(self, criteria, expected, execution_results):
pn_samples, results= self._prepare_kw_analysis(criteria) #Inicializamos las estructuras que se utilizan en el análisis para almacenar y procesar los resultados.
criteria_names=list(criteria.keys())
#Cálculo.
files_pos=0
for x in expected:
crit_pos=0
for crit_answer in x:
#crit_answer es la respuesta esperada.
pn_samples[criteria_names[crit_pos]][crit_answer]+=1
for z in execution_results[files_pos][crit_pos][2]:
results[crit_answer][criteria_names[crit_pos]][z]+=1
crit_pos+=1
files_pos+=1
#Calculamos el porcentaje para positivos y para negativos.
for x in list(criteria.keys()):
for i, j in results['OK'][x].items():
if pn_samples[x]['OK'] ==0:
results['OK'][x][i]=0
else:
results['OK'][x][i]=results['OK'][x][i]/pn_samples[x]['OK']
for i, j in results['KO'][x].items():
if pn_samples[x]['KO'] ==0:
results['KO'][x][i]=0
else:
results['KO'][x][i]=results['KO'][x][i]/pn_samples[x]['KO']
return results
def _prepare_best_kw_value_analysis(self, results, expected_results, num_crit):
percentages=dict() #X listas. una para cada criterio.
expected=dict() #X listas. una para cada criterio.
#Cogemos los resultados asociados a cada criterio.
for result in results:
for crit in range(num_crit):
if not crit in percentages:
percentages[crit]=list()
percentages[crit].append(result[crit][1])
#Cogemos los resultados esperados asociados a cada criterio.
for result in expected_results:
for crit in range(num_crit):
if not crit in expected:
expected[crit]=list()
expected[crit].append(result[crit])
return percentages, expected