-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathELM_DDM.py
258 lines (200 loc) · 11.3 KB
/
ELM_DDM.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
#-*- coding: utf-8 -*-
'''
Created on 6 de fev de 2017
By Gustavo Oliveira
Universidade Federal de Pernambuco, Recife, Brasil
E-mail: ghfmo@cin.ufpe.br
OLIVEIRA, Gustavo HFM et al. Time series forecasting in the presence of concept drift: A pso-based approach.
In: 2017 IEEE 29th International Conference on Tools with Artificial Intelligence (ICTAI).
IEEE, 2017. p. 239-246.
https://ieeexplore.ieee.org/document/8371949
'''
from ferramentas.Janela_deslizante import Janela
from ferramentas.Importar_dataset import Datasets
from ferramentas.Particionar_series import Particionar_series
from metricas.Metricas_deteccao import Metricas_deteccao
from detectores.DDM import DDM
from regressores.ELM import ELMRegressor
from graficos.Graficos_execucao import Grafico
from sklearn.metrics import mean_absolute_error
import time
import numpy as np
divisao_dataset = [0.8, 0.2, 0]
class ELM_DDM():
def __init__(self, dataset, n=300, lags=5, qtd_neuronios=10, w=8, c=8):
'''
construtor do algoritmo que detecta a mudanca de ambiente por meio do comportamento das particulas
:param dataset: serie temporal que o algoritmo vai executar
:param qtd_train_inicial: quantidade de exemplos para o treinamento inicial
:param tamanho_janela: tamanho da janela de caracteristicas para identificar a mudanca
:param n: tamanho do n para reavaliar o metodo de deteccao
:param lags: quantidade de lags para modelar as entradas da RNA
:param qtd_neuronios: quantidade de neuronios escondidos da RNA
:param limite: contador para verificar a mudanca
'''
self.dataset = dataset
self.n = n
self.lags = lags
self.qtd_neuronios = qtd_neuronios
self.w = w
self.c = c
self.tecnica = "ELM-DDM"
def Computar_estatisticas_DDM_desvio(self, vetor_caracteristicas, lags, ELM):
'''
Metodo para computar a deteccao de mudanca do erro por meio do DDM com desvio padrão tradicional
:param vetor_caracteristicas: vetor com uma amostra da serie temporal que sera avaliada para verificar a mudanca
:param lags: quantidade de lags para modelar as entradas da RNA
:param enxame: enxame utilizado para verificar a mudanca
:return: retorna a media ou o comportamento do enxame em relacao ao vetor de caracteristicas
'''
#particionando o vetor de caracteristicas para usar para treinar
particao = Particionar_series(vetor_caracteristicas, divisao_dataset, lags)
[caracteristicas_entrada, caracteristicas_saida] = particao.Part_train()
#realizando as previsoes e armazenando as acuracias
predicao_caracteristica = ELM.Predizer(caracteristicas_entrada)
erros = []
for i in range(len(caracteristicas_saida)):
erro = mean_absolute_error(caracteristicas_saida[i:i+1], predicao_caracteristica[i:i+1])
erros.append(erro)
return np.min(erros), np.std(erros), erros
def Executar(self, grafico = None):
'''
Metodo para executar o procedimento do algoritmo
:param grafico: variavel booleana para ativar ou desativar o grafico
:return: retorna 5 variaveis: [falsos_alarmes, atrasos, falta_deteccao, MAPE, tempo_execucao]
'''
################################################################################################################################################
################################# CONFIGURACAO DO DATASET ######################################################################################
################################################################################################################################################
#dividindo os dados da dataset dinamica para treinamento_inicial inicial e para uso do stream din�mico
treinamento_inicial = self.dataset[0:self.n] stream = self.dataset[self.n:]
################################################################################################################################################
################################# PERIODO ESTATICO #############################################################################################
################################################################################################################################################
#criando e treinando um enxame_vigente para realizar as previsoes
ELM = ELMRegressor(self.qtd_neuronios)
ELM.Tratamento_dados(treinamento_inicial, divisao_dataset, self.lags)
ELM.Treinar(ELM.train_entradas, ELM.train_saidas)
#ajustando com os dados finais do treinamento a janela de predicao
janela_predicao = Janela()
janela_predicao.Ajustar(ELM.train_entradas[len(ELM.train_entradas)-1:])
predicao = ELM.Predizer(janela_predicao.dados)
#janela com o atual conceito, tambem utilizada para armazenar os dados de retreinamento
janela_caracteristicas = Janela()
janela_caracteristicas.Ajustar(treinamento_inicial)
#atualizar por ECDD
[erro_min, desvio_min, erros] = self.Computar_estatisticas_DDM_desvio(janela_caracteristicas.dados, self.lags, ELM)
ddm = DDM(self.w, self.c)
ddm.armazenar_conceito(erro_min, desvio_min, erros)
################################################################################################################################################
################################# PERIODO DINAMICO #############################################################################################
################################################################################################################################################
#variavel para armazenar o erro do stream
erro_stream = 0
#variavel para armazenar as deteccoes
deteccoes = []
#variavel para armazenar os alarmes
alarmes = []
#variavel para armazenar o tempo inicial
start_time = time.time()
#vetor para armazenar a predicoes_vetor
if(grafico == True):
predicoes_vetor = [None] * len(stream)
erro_stream_vetor = [None] * len(stream)
#variavel auxiliar
mudanca_ocorreu = False
#entrando no stream de dados
for i in range(1, len(stream)):
#computando o erro
loss = mean_absolute_error(stream[i:i+1], predicao)
erro_stream += loss
#adicionando o novo dado a janela de predicao
janela_predicao.Add_janela(stream[i])
#realizando a nova predicao com a nova janela de predicao
predicao = ELM.Predizer(janela_predicao.dados)
if(grafico == True):
#salvando o erro
erro_stream_vetor[i] = loss
#salvando a predicao
predicoes_vetor[i] = predicao
if(mudanca_ocorreu == False):
#monitorando o erro
string_ddm = ddm.monitorar(loss, i)
#verificar se houve mudanca
if(string_ddm == ddm.alerta):
if(grafico == True):
print("[%d] Alarme" % (i))
alarmes.append(i)
#procedimento pos mudanca
if(string_ddm == ddm.mudanca):
if(grafico == True):
print("[%d] Detectou uma mudanca" % (i))
deteccoes.append(i)
#zerando a janela de treinamento
janela_caracteristicas.Zerar_Janela()
mudanca_ocorreu = True
else:
if(len(janela_caracteristicas.dados) < self.n):
#adicionando a nova instancia na janela de caracteristicas
janela_caracteristicas.Increment_Add(stream[i])
else:
#atualizando o enxame_vigente preditivo
ELM = ELMRegressor(self.qtd_neuronios)
ELM.Tratamento_dados(janela_caracteristicas.dados, divisao_dataset, self.lags)
ELM.Treinar(ELM.train_entradas, ELM.train_saidas)
#ajustando a janela de previsao
janela_predicao = Janela()
janela_predicao.Ajustar(ELM.train_entradas[len(ELM.train_entradas)-1:])
predicao = ELM.Predizer(janela_predicao.dados)
#atualizar por ECDD
[erro_min, desvio_min, erros] = self.Computar_estatisticas_DDM_desvio(janela_caracteristicas.dados, self.lags, ELM)
ddm = DDM(self.w, self.c)
ddm.armazenar_conceito(erro_min, desvio_min, erros)
#variavel para voltar para o loop principal
mudanca_ocorreu = False
#variavel para armazenar o tempo final
end_time = time.time()
#computando as metricas de deteccao
mt = Metricas_deteccao()
[falsos_alarmes, atrasos] = mt.resultados(stream, deteccoes, self.n)
#computando a acuracia da previsao ao longo do fluxo de dados
MAE = erro_stream/len(stream)
#computando o tempo de execucao
tempo_execucao = (end_time-start_time)
# variables to store
self.target = stream
self.predictions = predicoes_vetor
if(grafico == True):
print(self.tecnica)
print("Alarmes:")
print(alarmes)
print("Deteccoes:")
print(deteccoes)
print("Falsos Alarmes: ", falsos_alarmes)
print("Atrasos: ", atrasos)
print("MAE: ", MAE)
print("Tempo de execucao: ", tempo_execucao)
#plotando o grafico de erro
if(grafico == True):
g = Grafico()
g.Plotar_graficos(stream, predicoes_vetor, deteccoes, alarmes, erro_stream_vetor, self.n, atrasos, falsos_alarmes, tempo_execucao, MAE, nome=self.tecnica)
#retorno do metodo
return falsos_alarmes, atrasos, MAE, tempo_execucao
def main():
#instanciando o dataset
dtst = Datasets('dentro')
dataset = dtst.Leitura_dados(dtst.bases_reais(3), csv=True)
particao = Particionar_series(dataset, [0.0, 0.0, 0.0], 0)
dataset = particao.Normalizar(dataset)
#instanciando o algoritmo com sensores
n = 300
lags = 5
qtd_neuronios = 10
w = 8
c = 8
alg = ELM_DDM(dataset, n, lags, qtd_neuronios, w, c)
#colhendo os resultados
alg.Executar(grafico=True)
if __name__ == "__main__":
main()