Universidade Federal Do Rio Grande Do Sul Escola de Engenharia Curso de Graduação em Engenharia Elétrica
Universidade Federal Do Rio Grande Do Sul Escola de Engenharia Curso de Graduação em Engenharia Elétrica
Universidade Federal Do Rio Grande Do Sul Escola de Engenharia Curso de Graduação em Engenharia Elétrica
ESCOLA DE ENGENHARIA
CURSO DE GRADUAÇÃO EM ENGENHARIA ELÉTRICA
CAPA
Porto Alegre
10/11/2021
Leandro Vargas Barbosa
Porto Alegre
10/11/2021
Leandro Vargas Barbosa
Porto Alegre
2021
DADOS INTERNACIONAIS DE CATALOGAÇÃO NA PUBLICAÇÃO
Ficha Catalográfica
Leandro Vargas Barbosa
BANCA EXAMINADORA
__________________________________________
Prof. Dr. Roberto Petry Homrich
Universidade Federal do Rio Grande do Sul
__________________________________________
Prof. Dr. Fabio Souto De Azevedo
Universidade Federal do Rio Grande do Sul
__________________________________________
Profª. Drª. Gladis Bordin
Universidade Federal do Rio Grande do Sul
AGRADECIMENTOS
Dedico esse trabalho a minha amada Mãe Ivone Vargas (in memoriam) que sempre me
incentivou e acreditou em mim, e certamente estaria muito feliz de ver este sonho concretizado.
A minha irmã Franciele Vargas Barbosa (in memoriam) que tão breve nos deixou, seria tão bom
partilhar contigo este momento. Saudade Eterna.
Dedico também a meu Pai, José da Costa Barbosa, que igualmente me apoio e sempre
me aconselhou a trilhar os caminhos com respeito honra e honestidade. A minha querida Irmã
Fernanda Vargas Barbosa, saudades dos tempos que devíamos ter passado juntos e conversas
que não pudemos ter devido ao pouco tempo que tive presente.
A minha sogra Laura Solange Gonçalves Dias, pela grande ajuda principalmente dando
carinho e atenção ao meu filho seu neto suprindo minha ausência, durante a realização deste
projeto.
Em especial a minha amada companheira Lauriane Dias Freitas, que dividiu comigo boa
parte dessa jornada de engenharia, e a meu amado filho Guilherme Freitas Barbosa, não
chegaria até aqui sem vocês, sem seu apoio, sem seu carinho, sem sua compreensão e sem seu
amor.
This paper proposes a new stochastic model for projecting electricity consumption, using
optimization techniques through genetic algorithms applied to a recurrent neural network of the
Long Short Term Memory type. It highlights the effect of COVID-19 deaths on energy
consumption, and considers the random and attenuation effect of a social transient, which is
usually simplified in consumption projection models. The model built is presented in detail
initially using data from Rio Grande do Sul (southern state of Brazil) and later extends its scope
in a case study to Brazil in a pre-pandemic scenario in 2019 and in a pandemic scenario in 2020.
Tests of economic-climate and social variables are performed and show that the techniques used
are adequate to represent the problem under analysis.
LISTA DE QUADROS
QUADRO 1 - CENÁRIOS DE TESTE ........................................................................................................................... 80
LISTA DE ABREVIATURAS
1 INTRODUÇÃO ......................................................................................................................... 8
2 METODOLOGIA ..................................................................................................................... 14
REFERÊNCIAS .............................................................................................................................................. 86
ANEXOS ...................................................................................................................................................... 91
1 INTRODUÇÃO
Um problema relevante e complexo relacionado ao planejamento da gestão empresarial
de uma concessionária de energia elétrica diz respeito à projeção do consumo de energia
elétrica. Sabe-se que as projeções, em geral, não constituem um fim, mas um instrumento que
fornece informações para uma consequente tomada de decisão com objetivos específicos.
Assim, a projeção de consumo visa atender às necessidades dos consumidores com um nível de
qualidade satisfatório.
1.2 O Problema
No processo de planejamento tradicional, a projeção de consumo de energia elétrica de
curto prazo baseia-se principalmente em técnicas econométricas, através de correlações entre a
série histórica da demanda de energia elétrica e indicadores sócio-econômicos. Para o horizonte
de longo prazo, a projeção de demanda é realizada com uso da técnica de cenários sob incerteza.
No entanto, com o evento mundial da pandemia da COVID e seus efeitos sobre a este
consumo, uma vez que dados medidos de demanda atendida após o início da pandemia mostram
10
Uma vez que o consumo evolui de forma diferente nos distintos tipos de consumidores,
é usada a segmentação em classes de consumo aplicada no anuário da EPE [2], ou seja,
Residencial, Industrial, Comercial, Rural, Poder Público, Iluminação Pública, Serviço Público,
Consumo Próprio.
Após analisar alguns trabalhos, constata-se que em sua maioria bem como no próprio
relatório oficial produzido pela EPE, baseiam se em projeções enviadas pelas distribuidoras de
energia, estas por sua vez, se baseiam em estudos locais de projeção, demandas previstas e
contratadas pelos consumidores e expectativas públicas crescimentos ou (e.g.) implantação de
zona industrial. Os quais podem conter metas de políticas econômicas governamentais, que
podem ou não serem atingidas. Este estudo propõem uma visão alternativa, valendo-se do
histórico de demanda por região (da mesma forma que o estudo oficial), mas correlacionando-
os diretamente aos históricos de mercado obtendo as próprias de projeções. Em especial,
11
pretende-se observar, com enfoque especial, o evento aleatório COVID19 que não está
contemplado em nenhum destes estudos, conforme a revisão bibliográfica a seguir.
Apesar do erro médio baixo, houve 4 ocorrências com mais de 9,7% de erro calculando
o erro quadrático médio encontra-se 5,33 e apenas 46% das amostras ficaram abaixo desse
valor. A apresentação de apenas a média dos erros foi uma análise tendenciosa.
Considerando que a rede neural adaptativa conseguiu obter o melhor ajuste da rede,
talvez o uso de mais entradas possa refinar os resultados.
*obs.: WLS – Ajuste de pesos por método dos mínimos quadrados, do inglês: “Weighted least square state
estimation”;
**obs.: NN – Redes Neurais, do ingês:“Neural Network”
12
Obs.: PMUs, d inglês: “Phasor Measurement Unit” Unidade de Medição Fasorial / Síncrono Fasor
• A hybrid FCW-EMD and KF-BA-SVM based model for short-term load forecasting [6]
Estuda o carregamento de um transformador em uma subestação no sul da China
decompondo sinal dos dados históricos e projeta a carga futura com utilizando a correlação
entre o carregamento em diferentes dias da própria serie de dados, a aplica técnica de pesos
Fuzzy combined weigh e Filtro de Kalman.
• Energy Time Series Forecasting Based on Empirical Mode Decomposition and FRBF-
AR Model [7]
Modelo Híbrido Utiliza EMD método de decomposição empírica, obtendo funções de
modo intrínsecas (IMFs) e os resíduos aproximados através de FRBF - Fuzzy Radial Basis
Linear e essa previsão foi comparada aos dados da Australian Energy Market Operator
(AEMO) onde o erro quadrado médio foi de 1,24% que parece performar bem. Entretanto,
utiliza apenas a série histórica para determinar a predição alguns questionamentos de como é o
clima no sul da Austrália e se esse modelo se aplica a outras regiões necessitam de uma
discussão.
• A Short-Term Load Forecasting Method Using Integrated CNN and LSTM Network [8]
Defende a previsão de carregamento como alternativa a expansão da rede e divide o
estudo em: Short-term Load Forecasting (STLF): Próximas horas até próxima semana;
Medium-term Load Forecasting (MTLF): Mais de uma semana até alguns meses; e Long-term
Load Forecasting (LTLF): Alguns meses até próximos anos. Comparando com outros métodos
obteve melhores resultados de previsão utilizando modelo hybrido de long short-term memory
networks (LSTM) associado a convolutional neural network (CNN).
13
1.5 Objetivo
O presente trabalho objetiva a construção de um modelo estocástico de projeção de
consumo de energia elétrica, através do emprego de inteligência artificial e otimização genética
com um índice de erro inferior a 5%, utilizado para estabelecer esta meta a Resolução
Normativa nº 414 da ANEEL [9], na presença de evento aleatório de grandes proporções.
Complementam o trabalho oito Anexos, que tratam de análises detalhadas dos dados em
relação as apresentadas ao longo do texto, resultados dos testes realizados, e o código fonte
implementado.
14
2 METODOLOGIA
Este capítulo apresenta cada etapa em itens e subitens de modo a facilitar a leitura e a
repetibilidade deste experimento. Em linhas gerais, o trabalho investiga variáveis correlatas
com o consumo de energia elétrica no Brasil, visando à criação de um previsor de consumo de
energia. Para isto é realizado um estudo de caso com dados do Rio Grande do Sul, utilizando
entradas clássicas como meteorológicas e econômicas, como aspecto de inovação faz uso de
dados sociais e de saúde buscando descrever o comportamento anômalo da queda da demanda
durante a pandemia de COVID-19, utiliza dados de saúde e/ou de óbitos possam antever o
impacto da pandemia na economia. Se essa hipótese estiver correta pode-se evidenciar
cientificamente a correlação inversa entre a pandemia e o consumo, onde a causa da aceleração
da pandemia significa que o efeito é o freio do consumo/demanda.
Fonte: Autor
Fonte: [12]
Fonte:
[13]
Fonte: [14]
• DataSUS/tabnet
“Após a criação da Lei de Acesso à Informação, todas as informações produzidas ou
custodiadas pelo poder público são públicas, e portanto, disponíveis a todos os cidadãos,
exceto aquelas que são sigilosas por lei” [15]. Entretanto, mesmo disponíveis na maioria das
vezes não estão em um formato acessível ou amigável a uma análise de dados, sejam por estar
em formatos de imagem ou arquivos formato PDF, não estruturados, ou por estarem
pulverizados em vários sub arquivos. Pretendia-se inicialmente utilizar os dados de óbitos do
Portal Transparência Registro Civil [16], mas os mesmos não estavam disponíveis para o
mesmo período deste estudo, então a alternativa encontrada foi a de utilizar os dados do SUS
da plataforma DataSUS/Tabnet [17], que apesar de não ser o dado oficial consolidado pelo
Registro Civil, é uma amostra suficientemente representativa e confiável para que possa ser
utilizada.
• BCB - Banco Central do Brasil
O Banco Central do Brasil (também conhecido por BC, BACEN ou BCB) é uma
autarquia federal integrante do Sistema Financeiro Nacional, iniciou suas atividades em março
de 1965. O BC é uma das principais autoridades monetárias do país e tem autonomia para atuar
em busca da estabilidade de preços, zelar pela estabilidade e pela eficiência do sistema
financeiro, suavizar as flutuações do nível de atividade econômica e fomentar o pleno emprego.
18
Fonte: [21]
• Matplotlib [23]
O Matplotlib é uma biblioteca Python que fornece um grande conjunto de ferramentas
para a geração de gráficos dos mais variados tipos e formas, bem como o controle de todos os
atributos de impressão.
20
• Numpy [24]
NumPy é uma biblioteca Python que suporta arrays e matrizes multidimensionais,
possuindo uma larga coleção de funções matemáticas para trabalhar com estas estruturas. Foi
utilizada em conjunto com as outras ferramentas para manipular e gerar dados, funções e
resultados.
• Pandas [25]
Para a manipulação dos dados de forma tabular no formato de “data frames” e permitir
operações similares a linguagem SQL (Linguagem de Consulta Estruturada), assim como nas
análises de correlação e dispersão.
• Seaborn [27]
O Seaborn é uma biblioteca que a facilita a geração de gráficos, através de comandos
simples tem uma saída complexa sintetizando em poucas linhas os recursos da matplotlib.
• Statsmodels [28]
O Statsmodel é um pacote de análise estatística e deste foram utilizadas as
decomposições de sinal afim de verificar a periodicidade e tendência dos dados analisados.
• Versões utilizadas
Para o desenvolvimento do modelo proposto foram utilizadas as versões descritas na
Tabela 1.
21
Recurso Versão
matplotlib 3.2.2
numpy 1.19.5
pandas 1.1.5
Python 3.7.10
seaborn 0.11.1
sklearn 0.24.1
statsmodels 0.10.2
TensorFlow 2.5.0
Fonte: Autor
Faixa de Faixa de
Tipo Tensão Consumo Consumo Consumid
(...)
Data Consumidor Sistema UF SetorN1 (...) N1 2 Tensão N4 N1 N2 ores Consumo
Sudeste /
Centro- Poder A - Alta A-4 - 2,3 a 25 Não Não
1/12/2015 Cativo Oeste SP Público Tensão kV Aplicável Aplicável 32.0 353.000
Sudeste /
Centro- A - Alta AS - < 13,8 kV Não Não
1/8/2018 Livre Oeste RJ Comercial Tensão (Subterrâneo) Aplicável Aplicável 21.0 2.009.853
Fonte: [11]
22
Nele pode-se verificar que os dados fornecidos estavam agregados por classes de
consumo e níveis de tensão para cada mês de 2013 a 2018, e classificados em região e unidade
federativa.
• Comercial
o Comercial
o Templos Religiosos
• Consumo Próprio
o Outras Atividades
• Iluminação Pública
• Industrial
• Poder Público
o Estadual ou Distrital
23
o Federal
o Municipal
• Residencial
o Baixa Renda
• Rural
o Agroindústria
o Agropecuária
o Agropecuária Urbana
o Aquicultura
o Escola Agrotécnica
o Rural Residencial
• Serviço Público
o Tração Elétrica
• A - Alta Tensão
o A-2 - 88 a 138 kV
o A-3 - 69 kV
o A-3a - 30 a 44 kV
24
o A-4 - 2,3 a 25 kV
• B - Baixa Tensão
o B-4
▪ Baixa Renda
• 0-30 kWh
• 31-100 kWh
• 101-200 kWh
▪ Convencional
• 0-30 kWh
• 101-200 kWh
• 201-300 kWh
• 301-400 kWh
• 31-100 kWh
• 401-500 kWh
• 501-1000 kWh
25
Para uma visão detalhada foi realizado um recorte nos dados do estado do Rio Grande
do Sul de forma a aprofundar o problema em um estudo de caso a um custo computacional
menor antes de expandir o método a todos os estados da federação e se conseguir tratar de
maneira satisfatória um dado menor.
Fonte: Autor
Já ao analisar a distribuição deste consumo ao logo dos meses, pode-se notar quais são
as cargas que apresentam uma variação ao longo do ano. A Figura 8 mostra que o setor Rural
apresenta a maior variação ao longo do ano.
26
Fonte: Autor
Para validar esta informação e verificar que essa oscilação se repete ao longo da série de
2013 à 2018 foi feita uma análise de dispersão através do desvio padrão, onde os resultados
estão mostrados na Figura 9.
Fonte: Autor
Fonte: Autor
Fonte: Autor
Rural no RS sob ela própria defasando-a mês a mês obtém-se o gráfico da Figura 12 onde
percebe-se uma correlação negativa após uma defasagem de 4 meses o que enseja uma possível
dependência das estações do ano. A característica senoidal reforça essa hipótese e a envoltória
decrescente reafirma a tendência de incremento no consumo com o passar dos anos.
Fonte: Autor
Ainda foi realizado uma breve análise sobre os outros setores N1 onde se pode verificar
seguindo os mesmos critérios uma sazonalidade clara nos setores N1: Residencial Comercial,
Rural, Poder Público. Um comportamento não diretamente correlato a sucessão dos meses do
ano, nos setores N1: Industrial, Iluminação Pública, Serviço Público, Consumo Próprio,
melhores descritos no Anexo 1 – Análise de Consumo Mensal por Setor N1 no RS.
Para verificar quais destes dados seriam relevantes e se seria possível tomar os dados de
uma estação como representação do todo foi realizada uma análise de correlação de Pearson
para cada uma destas variáveis comparando sempre estre todas as estações e com o valor médio
de todas elas para cada medida. Obtendo ao avaliar dados INMET do RS de 2013 a 2018, os
mapas de correlação cruzada conforme exemplo da Figura 13, os mapas completos podem ser
consultados no Anexo 2 – Mapas de Correlação Meteorológicos.
*
Fonte: Autor
Para cada uma destas variáveis foi tomada a média das correlações e em seguida
ranqueadas em ordem decrescente para verificar quais seriam as estações mais representativas
Figura 14.
*Obs.: As figuras destes mapas (exemplo da Figura 13) foram descritas em anexo para possibilitar ao
leitor as leia em tamanho apropriado.
30
Figura 14 - Ranking das Maiores Médias de Correlação Entre Estações Automáticas INMET Por Variável
meteorológica
Fonte: Autor
Verificou-se que a estação mais significativa não é nenhuma delas e sim a média de
todas, que teve maior correlação média em 5 dentre as 6 variáveis avaliadas.
Na Figura 15 não se observou um padrão bem definido no número médio de dias com
precipitação.
Fonte: Autor
Fonte: Autor
Fonte: Autor
Fonte: Autor
Na Figura 19, referente ao perfil dos ventos máximos é verificado um padrão mais
discreto, mas presente com um pico em outubro.
33
Fonte: Autor
Fonte: Autor
Após verificar-se quais variáveis tem um comportamento bem definido nota-se que os
principais candidatos seriam a Temperatura, a Pressão e o Vento.
de Saúde (OMS) declarou o surto como uma pandemia, que é uma epidemia que ganha escala
global.”(...)
Como no início deste trabalho pouco se sabia sobre os efeitos que uma paralização
pandêmica poderia ser capaz de produzir na economia e por conseguinte no consumo de energia
elétrica, este trabalho propõe-se a verificar se há evidencias diretas deste possível impacto.
Corroborando essa escolha, o relatório divulgado pelo Banco Central do Brasil – BCB
[19], correlaciona o índice de atividade econômica IBC-BR com os índices de mortalidade por
COVID ou SRAG constatando que: “Os resultados da análise sugerem a existência de uma
relação contemporânea negativa entre a crise sanitária e o nível de atividade econômica.
.Contudo, essa relação não é constante ao longo do tempo”(...) "indicando que um agravamento
da crise sanitária está associado a deterioração da atividade econômica”. O mesmo relatório
pondera que uma atenuação no agravamento econômico apesar do agravamento da COVID
pode ser correlacionado com o aumento mobilidade e assim favorecendo as atividades
econômicas.
Na Figura 21 – pode-se verificar o comportamento das mortes ao longo dos anos e assim
pode-se verificar que o aumento percebido ao longo de dos anos de 2019 e 2020 causados direta
ou indiretamente pela pandemia.
35
Fonte: Autor
É evidente a quebra do padrão anterior nos anos de 2020 e 2021. Estes dados são
oportunamente usados na segunda etapa de modelagem, onde o enfoque é dado para a
generalização do modelo e avaliação de novas variáveis.
Essa quebra de tendência e ruptura de padrão da própria série fica mais evidente
ao analisar-se a decomposição da série temporal na Figura 22.
Fonte: Autor
36
Estes dados serão utilizados na segunda etapa de modelagem onde o enfoque dado para
generalização do modelo e avaliação de novas variáveis.
• Análise dos Dados de atividade econômica fornecidos pelo Banco Central do Brasil
Para avaliar a atividade econômica utilizou-se o indicador oficial do IBC-BR, ilustrado
na Figura 23.
Fonte: Autor
Novamente verifica-se uma a quebra do padrão anterior nos anos de 2020 e 2021. Com
um abrupto degrau em 2020. Essa quebra de tendência e ruptura de padrão da própria série fica
mais evidente ao analisar-se a decomposição da série temporal na Figura 24.
37
Fonte: Autor
Estes dados serão utilizados na segunda etapa de modelagem onde o enfoque dado para
generalização do modelo e avaliação de novas variáveis.
Ao observar a Figura 26, não é possível em uma análise preliminar um padrão bem
definido.
38
Fonte: Autor
Já na Figura 26, verificamos que uma tendencia de alta durante a pandemia, a partir do
início de 2020. Após um período de estabilidade.
Fonte: Autor
39
Fonte: Autor
Essa quebra de tendência e ruptura de padrão da própria série fica mais evidente ao
analisar-se a decomposição da série temporal na Figura 28 ainda verifica-se que a mudança de
padrão de tendencia e resíduo ocorre pouco antes que na Essa quebra de tendência e ruptura de
padrão da própria série fica mais evidente ao analisar-se a decomposição da série temporal na
Figura 24.
Fonte: Autor
Estes dados serão utilizados na segunda etapa de modelagem onde o enfoque dado para
generalização do modelo e avaliação de novas variáveis.
• 0.9 para mais ou para menos indica uma correlação muito forte;
• 0.7 a 0.9 positivo ou negativo indica uma correlação forte;
• 0.5 a 0.7 positivo ou negativo indica uma correlação moderada;
• 0.3 a 0.5 positivo ou negativo indica uma correlação fraca;
• 0 a 0.3 positivo ou negativo indica uma correlação desprezível.
Fonte: Autor
Fonte: Autor
de ativação, arbitrária a qual retorna um valor de saída. (Figura 31), este modelo é chamado de
perceptron o qual teve as primeiras publicações e implementações por Rosenblatt em 1957 [33].
Fonte: [34]
A Célula LSTM Foi proposta foi proposta em 1997 por Sepp Hochreiter e Jurgen
Schmidhuber e aperfeiçoada em 2014 por Alex Graves, Haşim Sak e em 2015 por Wojciech
Zaremba e sua estrutura básica está descrita na Figura 32, onde tem-se um comportamento
básico, similar ao neurônio Perceptron da figura anterior, com uma modificação que é
comparada a uma memória onde o estado da própria célula em uma iteração anterior
representada pelo índice (𝑡−1) influencia em um estado atual de índice (𝑡) onde os sinais ℎ𝑡
funcionam como um estado de curto prazo e 𝑐(𝑡) como um estado de longo prazo
44
Fonte: [34]
Uma célula LSTM pode aprender a reconhecer uma entrada importante, armazená-la no
estado de longo prazo, aprender a preservá-la pelo tempo necessário e aprender a extraí-la
sempre que for preciso. [34]
Fonte: [35]
46
Fonte: Autor
Nesse estudo também será avaliada uma variação de RNN, chamada Bidirecional RNN
(BRNN), essa estrutura proposta por Mike Schuster e Kuldip K. Paliwal [36], onde a célula
utiliza tanto dados de um estado futuro (𝑡 + 1), quanto de um estado passado (𝑡 − 1) para
determinar o estado (𝑡).
47
Fonte: [36]
2.5.5 Aprendizagem
É denominado aprendizagem o processo de ajuste iterativo dos pesos que é realizado
comparando os valores de saída conhecidos com os valores calculados, preditos, pela RNA,
onde eles são atualizados por um processo de retro propagação do erro que é calculado e
atualizado para cada ramo a cada interação, para este ajuste pode-se utilizar vários métodos.
Este estudo encontrou melhores resultados utilizando o método Adam [37].
Fonte: Autor
(1)
[1]
2.5.8 Implementação
Para implementação da MLP foi utilizado principalmente o módulo
sklearn.neural_network.MLPRegressor da biblioteca Scikit Learn.
49
Já, a rede LSTM foi implementada através do módulo Keras da biblioteca TensorFlow.
Momento 2: Para ter maior controle de cada ajuste foi elaborada uma função similar a estratégia
do GridSearchCV, entretanto em uma função de laço que permitiu a análise de cada parâmetro
de uma maneira semiautomatizada.
Momento 3: Como para a definição das dimensões da rede não se encontrou uma referência
determinística. Optou-se por uma estratégia de otimização por algoritmo genético que é descrita
na seção2.6.
Fonte: Autor
Por ter um desempenho muito próximo e por possuir uma profundidade muito menor
que o primeiro (4 vs 9), se optou pela estrutura (8,16,32,4).
o identity, 𝑓(𝑥) = 𝑥
1
o logistic, 𝑓(𝑥) =
1 + 𝑒𝑥𝑝(−𝑥)
o tanh, 𝑓(𝑥) = 𝑡𝑎𝑛ℎ(𝑥)
o relu, 𝑓(𝑥) = 𝑚𝑎𝑥(0, 𝑥)
De todas as funções de ativação testadas a que teve melhor desempenho foi a relu
conforme representadas na Figura 38
51
Fonte: Autor
Fonte: Autor
Alfa (alpha)
Foram pesquisados valores de alfa: (1,0.1,0.01,0.001,0.0001,0.00001)
52
Como a alteração não trouxe melhor de desempenho (Figura 40), foi mantido o valor
default = 0,0001
Fonte: Autor
Como a alteração não trouxe melhor de desempenho (Figura 41), foi mantido o valor
default = 0,001
Fonte: Autor
Embaralhamento (shuffle)
Foram pesquisados de embaralhamento dos dados de entrada: {True, False}
Como a alteração não trouxe melhoria de desempenho (Figura 42), foi mantido o valor
default = True
Fonte: Autor
Beta 1
Parâmetro 1 para ajuste de Bias
Foram pesquisados valores de Beta 1: (0.001, 0.01, 0.1, 0.2, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
0.95, 0.99) e em seguida de (0.91, 0.92, 0.93, 0.94, 0.95, 0.96, 0.97, 0.98. O melhor resultado
foi em Beta 1 = 0.94 conforme Figura 43 e Figura 44.
Fonte: Autor
54
Fonte: Autor
Beta 2
Parâmetro 2 para ajuste de Bias
Foram pesquisados valores de Beta 2: (0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 0.995, 0.999,
0.9999), em seguida buscou-se um refinamento avaliando os parâmetros: (0.996, 0.997, 0.998,
0.999, 0.9991, 0.9992, 0.9993, 0.9994). O melhor resultado foi encontrado no valor default =
0.999, o qual foi o escolhido mantido conforme Figura 45 e Figura 46.
Fonte: Autor
55
Fonte: Autor
Epsilon
Valor numérico de estabilidade no algoritmo adam
Foram pesquisados valores de estabilidade epsilon: (1-e10, 1-e09, 1-e08, 1-e07, 1-e06,
1-e05, 1-e04, 1-e03). O melhor resultado foi em encontrado no valor 1-e10 o qual foi o
escolhido mantido conforme Figura 47.
Fonte: Autor
56
Fonte: Autor
• Seleção
Seleção é o processo pelo qual uma certa proporção de indivíduos é selecionada
para acasalar entre si e gerar novos descendentes. Assim como na seleção natural da vida real,
os indivíduos mais aptos têm maiores chances de sobreviver e, portanto, de passar seus genes
para a próxima geração. Embora existam versões com mais indivíduos, geralmente o processo
de seleção combina dois indivíduos, criando pares de indivíduos. Onde existem quatro
estratégias principais, descritas a seguir.
3. Roleta: Esta estratégia também segue um princípio aleatório, mas os indivíduos mais
aptos têm maiores probabilidades de serem selecionados.
• Delimitação do problema
Como na busca anterior, foi encontrada como melhor arranjo a configuração de camadas
ocultas a configuração (8,16,32,4) e considerando que para cada avaliação de aptidão será
necessário treinar e validar a RNA. Definiu-se como espaço de busca uma rede de até 4 camadas
ocultas com dimensão de no máximo 64 neurônios por camada. Como a quantidade de
neurônios é quantizada, cada camada poderá ter apenas números inteiros de N neurônios. Ou
seja, cada indivíduo terá um cromossomo representado por um conjunto de quatro genes:
{N,N,N,N} onde 𝑁 = {0,1,2, … ,64}
*obs.: Aleatoriamente - Refere-se a número pseudo aleatório gerado pela linguagem de programação
58
Fonte: Autor
• Arca de Genoma
Para evitar que um mesmo código genético seja testado mais de uma vez, foi criada uma
rotina que armazena em arquivo e recupera os valores de erro e aptidão para cada rodada
completa do algoritmo.
59
• Função de aptidão
Para cada sequência gerada é realizado o teste de aptidão que parametriza e testa a MLP
para um mesmo caso de teste, retornando os valores de aptidão. Caso a mesma sequência já
tenha sido testada o algoritmo recupera o valor do teste anterior promovendo assim um ganho
de performance (Figura 50).
Fonte: Autor
• Elite
Para garantir que o mais apto seja mantido nos processos de mutação na próxima
geração, são selecionados os dois indivíduos mais aptos garantindo sua sobrevivência e
mantendo o menor erro no laço para avaliação do processo de parada (Figura 51).
Fonte: Autor
60
• Progenitores
Após testados cada indivíduo possui uma aptidão medida, essa aptidão é
normalizada pela soma de todas as aptidões da população atual, e esta aptidão normalizada é
utilizada como distribuição de probabilidade para uma seleção aleatória, onde em uma analogia
com uma roleta de jogos, os mais aptos tem a maior probabilidade de ser escolhido
aleatoriamente* (Figura 52).
Fonte: [39]
Após selecionados os progenitores são agrupados aos pares para que possam
realizar cruzamento genético (Figura 53)
Fonte: Autor
61
• Cruzamento
Para no cruzamento evitar que sejam gerados clones, é gerada uma chave aleatória de 4
bits diferentes de “0000” e “1111” com a mesma probabilidade para cada posição ser 0 ou 1.
Esta chave define qual descendente (C ou D) herda qual gene, de maneira que, nesta etapa, C é
o inverso de D no que se refere a posição do gene herdado do progenitor A ou B(Figura 54).
Fonte: Autor
• Mutação
Para garantir que novas sequencias sejam testadas a partir de um parâmetro de
probabilidade de mutação inicial, é gerada uma chave sequencial de forma similar ao processo
de cruzamento garantindo que haja ao menos uma mutação e um progenitor fictício gerado
62
aleatoriamente a cada mutação. Caso o algoritmo fique preso no mesmo erro mínimo, o fator
de mutação é aumentado (Figura 55).
Fonte: Autor
• Critérios de Parada
Como critérios de parada tem-se a seguinte sequência:
o Parada por atingimento de alvo: caso o erro predefinido como alvo, seja atingido
de maneira precoce;
o Parada por erro travado: caso o erro fique parado por 4 gerações o fator de
mutação é incrementado em 10% até o limite de 100%, se o erro persistir travado
por um número de gerações maior que o predefinido então é realizada a parada.
o Parada por número máximo de gerações: A parada ocorre após superado o
número máximo de gerações predefinido.
63
Fonte: Autor
• Nova Geração
A nova geração é formada pela composição dos progenitores, seus descendentes
e versões mutadas aleatoriamente dos descendentes e da elite. Caso algum membro da elite não
seja selecionado como progenitor o mesmo será incluído na próxima geração, para que seja
garantida a métrica de ter o mais indivíduo com melhor aptidão sempre presente nas gerações
seguintes (Figura 57).
64
Fonte: Autor
3 (4)
𝑛𝑜𝑣𝑎 𝑝𝑜𝑝𝑢𝑙𝑎çã𝑜 = 𝑖𝑛𝑖𝑃𝑂𝑃 + 2
2
3 (5)
𝑛𝑜𝑣𝑎 𝑝𝑜𝑝𝑢𝑙𝑎çã𝑜 = 𝑖𝑛𝑖𝑃𝑂𝑃 + 4
2
65
3 3 (6)
𝑖𝑛𝑖𝑃𝑂𝑃 + 2 ≤ 𝑃𝑜𝑝𝑢𝑙𝑎çã𝑜 ≤ 𝑖𝑛𝑖𝑃𝑂𝑃 + 4
2 2
Fonte: Autor
Parâmetros de comparação:
Fonte: Autor
Outro aspecto relevante a ser avaliado é a dispersão dos resultados encontrados para 30
mil combinações testadas, o que representa 0,17% das combinações possíveis, onde ao ajustar
aleatoriamente a MLP o melhor desempenho obtido foi o de 5,23% . Lembrando que esse valor
está tendendo ao menor valor uma vez que o algoritmo genético cria mais descendentes do
67
indivíduo mais apto o que fica evidenciado pala maior barra a esquerda (em torno de 7,79% e
8,29%).
Fonte: Autor
Também forma realizados testes que iniciaram com pelo menos um indivíduo dentre o
segundo e o décimo melhor testado, nesse caso o algoritmo conseguiu encontrar o melhor
resultado em até 3 iterações, já ao iniciar randomicamente os testes mais lentos levaram em
torno de 32 gerações para atingir um resultado muito próximo do melhor encontrado até o
momento, considerando uma probabilidade de mutação fixa de 20%, alterando iterativamente
este valor pode se obter o resultado com menos gerações.
Fonte: Autor
68
Fonte: Autor
poderia ser de três formas: totalmente interconectada; 90% interconectada (dropout = 0,1); ou
80% interconectada (dropout = 0,2).
Cada uma das camadas poderia ter até 64 neurônios (onde 0 (zero) descartaria a
camada), onde as duas primeiras poderiam assumir duas formas LSTM (unidirecional) ou
BLSTM (bidirecional LSTM), as quatro últimas camadas poderiam assumir apenas o formato
MLP, após testes descritos em Anexo 4 – Resultado Teste: 2 camadas (Bi) LSTM e 4 camadas
MLP com dropout, onde foi possível aproximar a série de 2018 com um erro (MAPE) de 0,0327
o que é um resultado melhor que o obtido apenas com a estrutura anterior apenas com camadas
MLP (Figura 63).
Fonte: Autor
• Generalização LSTM
Como este estudo foi segmentado inicialmente para viabilizar uma análise mais
profunda separando para isso somente o consumidor rural no estado do Rio Grande do Sul. São
realizadas duas generalizações. A primeira generalizando para qualquer classe de consumidor,
e a segunda para qualquer estado e brasil;
Fonte: Autor
Em seguida foi realizado o teste de ajuste cada SetorN1 individualmente, ou seja, uma
rede com apenas uma saída em uma estrutura paralela onde foram compartilhados apenas as
outras entradas (que não são as classes de consumo) conforme descritos na Figura 65. Ambos
os processos foram ajustados para que demorassem em torno de 24h.
Fonte: Autor
Fonte: Autor
72
Fonte: Autor
Avaliando os erros para cada segmento nas Figura 68 e Figura 69, é possível validar
esta afirmação, de que uma rede para cada SetorN1 consegue uma melhor previsão do que uma
única rede com todas os Setores para o método de ajuste discutido até o momento e com os
hiper parâmetros e entradas utilizadas até este momento, cabe ainda ressaltar que apesar de
obter precisões distintas nos dois testes, o pior caso se manteve, o que nos dá indícios de que
ou as entradas escolhidas não sejam adequadas para prever o SetorN1 Consumo Próprio.
73
Fonte: Autor
Fonte: Autor
74
3 ESTUDO DE CASO BR
Na generalização do método por unidade da federação ou para o Brasil considera-se
que, a previsão do consumo de energia elétrica de um estado é similar a qualquer outro estado,
e que o algoritmo genético proposto permite ajustar a rede da mesma forma que o fez para o
estado do RS, segmentado por SetorN1 ou não. O modelo proposto tem suas estradas ajustadas
para levar em conta todas as estações meteorológicas disponíveis no INMET e assumindo que
as premissas utilizadas até este momento continuem válidas, é omitida a etapa de análise dos
dados como foi realizado no estudo de caso RS. Assumindo que se o resultado do estudo de
caso BR for válido então as premissas também são validas.
Na Figura 70 pode-se verificar que no ano de 2018 o consumo do Brasil não teve uma
variabilidade tão grande quanto o estudo de caso RS, mas ainda assim o método obteve um bom
ajuste dos valores preditos em comparação aos valores reais verificados. O que é comprovado
na Figura 71, a qual traz os valores de erro dentro dos limites estipulados como meta para este
estudo de 𝑀𝐴𝑃𝐸 <= 5%.
75
Fonte: Autor
76
Fonte: Autor
Para avaliar o impacto destas novas variáveis na previsão foi realizado a previsão de
carga com os dados de 2013 a 2017 prevendo 2018 (Figura 72). Para servir de parâmetro para
as demais. E para garantir a repetibilidade e a comparação com os mesmos parâmetros para a
definição da rede via algoritmo genético. Foi definida uma população inicial de 16 genomas e
32 épocas de iteração para cada classe de consumo.
77
Fonte: Autor
No avanço da previsão para o ano de 2020 é possível verificar que todas as previsões
não fornecem resultados adequados, como pode-se verificar na Figura 73.
78
Fonte: Autor
econômica IBC-BR, já segundo o estudo sobre as mortes por covid EPICOVID [32] há no
Brasil uma sub notificação de casos e óbitos por COVID-19.
Assim uma vez que não há estatística previa, e considerando que outras doenças
deixaram de ser tratadas no momento correto devido á pandemia, assumiu-se que o mais
confiável seria utilizar o número de óbitos totais disponibilizados pela plataforma
tabnet/DATASUS [17], apesar de não ser o número total de óbitos que estaria disponível no
portal dos cartórios de registro civil [40], os dados fornecidos pelos mesmos não contemplam
todo o período deste estudo, e assim, entende-se que os dados do SUS representam parcela
suficiente significativa do todo.
Para melhor definir o cenário econômico, também foram agregadas como variáveis de
entrada IPCA e IBOV, e estes escolhidos pela possibilidade de obter-se estudos de projeção
oficiais, futuras pelo próprio Banco Central do Brasil e Bovespa.
Fonte: Autor
80
Colocando então sob análise principal a variável óbitos que apresentou maior
segmentação na Figura 74, é possível verificar que o aumento no número de óbitos gerou
impactos na bolsa de valores, na inflação, na atividade econômica e no consumo de energia
elétrica, quebrando o padrão de todas estas variáveis (Figura 75) e justificando a escolha desta
como principal variável em análise.
Para garantir a correta escolha de variáveis foram realizados 16 testes de forma a testar
todos os arranjos possíveis para as variáveis escolhidas e os resultados destes testes são
mostrados no Quadro 1. No melhor arranjo testado (além das variáveis climáticas usadas em
todos os cenários), foi obtido pelas entradas IBCBR, IPCA e Óbitos, é possível observar que
estas variáveis estão presentes em 4 dos 5 melhores resultados.
Entradas MAPE
Óbitos
IBCBR
Clima
IBOV
IPCA
Figura 76 - Teste Valor Real vs Predito 2020 e MAPE (BR Resenha IBCBR, IPCA, Óbitos)
Fonte: Autor
82
Reaplicando esta mesma estrutura para a previsão de 2018 a fim de verificar se as novas
variáveis interfeririam positivamente também num cenário sem pandemia. Pode-se verificar na
Figura 77 teve um desempenho levemente superior quando comparados os erros (MAPE) da
Figura 72, demonstrando que o uso destas novas variáveis é mais relevante em período de
pandemia do que fora dele.
Figura 77 - Teste Valor Real vs Predito 2018 e MAPE (BR Resenha IBCBR, IPCA, Óbitos)
Fonte: Autor
83
4 CONSIDERAÇÕES FINAIS
4.1 Conclusões
A análise das aplicações do modelo aqui proposto comprovou que a técnica escolhida,
regressor LSTM/MLP, associada a um dimensionamento da rede neural através de algoritmo
genético, foi eficiente na previsão do consumo de energia elétrica. A inclusão da variável do
número de óbitos, associada as tradicionais variáveis econômicas e sociais, mesmo em um
contexto adverso como a pandemia de COVID-19, resultou em melhoria na previsão de
consumo de energia elétrica.
REFERÊNCIAS
ANEXOS
92
Fonte: Autor
Fonte: Autor
93
Fonte: Autor
Industrial
Figura 81 - Perfil de Consumo Mensal, Detalhe: Setor N1 =Industrial, UF = RS
Fonte: Autor
94
Fonte: Autor
Fonte: Autor
95
Comercial
Figura 84 - Perfil de Consumo Mensal, Detalhe: Setor N1 = Comercial, UF = RS
Fonte: Autor
Fonte: Autor
96
Fonte: Autor
Rural
Figura 87 - Perfil de Consumo Mensal, Detalhe: Setor N1 =Rural, UF = RS
Fonte: Autor
97
Fonte: Autor
Fonte: Autor
98
Poder Público
Figura 90 - Perfil de Consumo Mensal, Detalhe: Setor N1 = Poder Público, UF = RS
Fonte: Autor
Figura 91 - Decomposição Sazonal Multiplicativa do Perfil de Consumo, Detalhe: Setor N1 = Poder Público e
UF = RS
Fonte: Autor
99
Fonte: Autor
Iluminação Pública
Figura 93 - Perfil de Consumo Mensal, Detalhe: Setor N1 = Iluminação Pública, UF = RS
Fonte: Autor
100
Fonte: Autor
Fonte: Autor
101
Serviço Público
Figura 96 - Perfil de Consumo Mensal, Detalhe: Setor N1 = Serviço Público, UF = RS
Fonte: Autor
Figura 97 - Decomposição Sazonal Multiplicativa do Perfil de Consumo, Detalhe: Setor N1 = Serviço Público e
UF = RS
Fonte: Autor
102
Fonte: Autor
Consumo Próprio
Figura 99 - Perfil de Consumo Mensal, Detalhe: Setor N1 = Consumo Próprio, UF = RS
Fonte: Autor
103
Figura 100 - Decomposição Sazonal Multiplicativa do Perfil de Consumo, Detalhe: Setor N1 = Consumo
Próprio e UF = RS
Fonte: Autor
Fonte: Autor
104
Fonte: Autor
105
Figura 103 - Mapa de Correlação Cruzada do Acumulado de Precipitação por Mês no RS de 2013 a 2018 por Estação Meteorológica.
Fonte: Autor
106
Figura 104 - Mapa de Correlação Cruzada da Média de Pressão por Mês no RS de 2013 a 2018 por Estação Meteorológica.
Fonte: Autor
107
Figura 105 - Mapa de Correlação Cruzada da Média de Temperatura por Mês no RS de 2013 a 2018 por Estação Meteorológica.
Fonte: Autor
108
Figura 106 - Mapa de Correlação Cruzada da Velocidade Máxima do Vento por Mês no RS de 2013 a 2018 por Estação Meteorológica.
Fonte: Autor
109
Figura 107 - Mapa de Correlação Cruzada da Velocidade Média do Vento por Mês no RS de 2013 a 2018 por Estação Meteorológica.
Fonte: Autor
110
Fonte: Autor
111
Fonte: Autor
112
Anexo 4 – Resultado Teste: 2 camadas (Bi) LSTM e 4 camadas MLP com dropout caso:
RS: Rural
->Algoritmo genético de otimização -----------------------------------
Nova População = True
Recupera memória de iterações passadas = False
Gerações máximas = 200
Mais aptos selecionados em memória = 0
Tamanho da população = 32
Número de Genes = 13
Limite de valores para cada Gene = (0, 64)
Probabilidade de Mutação inicial = 0.2
Casais por época = 8
Limite de épocas parado no mesmo erro = 200
Erro Alvo = 1e-05
------------------------------------------------------------------------
Estrutura:
->BILSTM(41)->d(0.1)->LSTM(49)->d(0.1)->MLP(44)->d(0.2)->MLP(46)->d(0.1)-
>MLP(41)->d(0.1)->MLP(28)->
CPU times: user 16h 25min 41s, sys: 43min 37s, total: 17h 9min 19s
Fonte: Autor
113
Fonte: Autor
114
Anexo 5 – Resultado Teste: 2 camadas (Bi) LSTM e 4 camadas MLP com Dropout caso:
RS Estratificado Com Setores N1, Rede Única para Todos os Setores
->Algoritmo genético de otimização -----------------------------------
Nova Populaçao = True
Recupera memória de iterações passadas = False
Gerações máximas = 100
Mais aptos selecionados em memória = 0
Tamanho da população = 64
Número de Genes = 13
Limite de valores para cada Gene = (0, 64)
Probabilidade de Mutação inicial = 0.2
Casais por época = 16
Limite de épocas parado no mesmo erro = 200
Erro Alvo = 1e-05
------------------------------------------------------------------------
Estrutura:
->LSTM(50)->d(0.1)->LSTM(46)->d(0.2)->MLP(62)->d(0.2)->MLP(50)->d(0.1)-
>MLP(42)->d(0.1)->MLP(51)->
CPU times: user 20h 29min 11s, sys: 54min 3s, total: 21h 23min 15s
Fonte: Autor
115
Fonte: Autor
116
Fonte: Autor
117
Anexo 6 – Resultado Teste: 2 camadas (Bi) LSTM e 4 camadas MLP com Dropout caso:
RS Estratificado Com Setores N1, Uma rede para cada Setor
->Algoritmo genético de otimização -----------------------------------
Nova Populaçao = True
Recupera memória de iterações passadas = False
Gerações máximas = 32
Mais aptos selecionados em memória = 0
Tamanho da população = 32
Número de Genes = 13
Limite de valores para cada Gene = (0, 64)
Probabilidade de Mutação inicial = 0.2
Casais por época = 16
Limite de épocas parado no mesmo erro = 200
Erro Alvo = 1e-05
------------------------------------------------------------------------
Tempo de Processamento: 22h52m
Consumo:
MAPE = 0.021641
gen = [39 58 56 16 63 44 50 26 39 40 2 18 1]
->LSTM(26)->d(0.2)->BILSTM(39)->d(0.2)->MLP(40)->d(0.1)->MLP(2)->d(0.2)-
>MLP(18)->d(0.2)->MLP(1)->
Comercial:
MAPE = 0.017043
gen = [31 0 55 55 39 57 3 12 0 42 0 24 18]
->LSTM(12)->d(0.1)->MLP(42)->d(0.1)->MLP(24)->d(0.1)->MLP(18)->
Consumo Próprio:
MAPE = 0.153316
gen = [60 62 35 56 26 21 47 23 9 61 41 19 34]
->BILSTM(23)->d(0.1)->BILSTM(9)->d(0.2)->MLP(61)->d(0.2)->MLP(41)->d(0.1)-
>MLP(19)->d(0.1)->MLP(34)->
Iluminação Pública:
MAPE = 0.019208
gen = [54 54 55 20 26 54 25 4 61 47 50 49 11]
->BILSTM(4)->d(0.1)->BILSTM(61)->d(0.2)->MLP(47)->d(0.2)->MLP(50)->d(0.2)-
>MLP(49)->d(0.1)->MLP(11)->
Industrial:
MAPE = 0.03043
gen = [37 42 23 54 23 1 7 0 58 48 23 50 39]
->BILSTM(58)->d(0.2)->MLP(48)->d(0.1)->MLP(23)->d(0.1)->MLP(50)->d(0.1)-
>MLP(39)->
Poder Público:
MAPE = 0.029517
gen = [39 39 24 22 4 50 54 33 59 8 2 2 27]
->LSTM(33)->d(0.2)->LSTM(59)->d(0.2)->MLP(8)->d(0.2)->MLP(2)->d(0.2)-
>MLP(2)->d(0.2)->MLP(27)->
Residencial:
MAPE = 0.042109
gen = [41 28 62 52 7 50 42 18 60 7 2 20 33]
->LSTM(18)->d(0.2)->BILSTM(60)->d(0.2)->MLP(7)->d(0.1)->MLP(2)->d(0.2)-
>MLP(20)->d(0.2)->MLP(33)->
Rural:
MAPE = 0.036827
gen = [18 28 47 39 58 50 1 21 56 62 42 62 25]
118
->BILSTM(21)->d(0.1)->BILSTM(56)->d(0.1)->MLP(62)->d(0.2)->MLP(42)->d(0.2)-
>MLP(62)->d(0.1)->MLP(25)->
Serviço Público:
MAPE = 0.023087
id_arca = 591
gen = [22 63 58 13 53 17 0 35 51 63 34 50 26]
->BILSTM(35)->d(0.2)->LSTM(51)->d(0.1)->MLP(63)->d(0.1)->MLP(34)->d(0.1)-
>MLP(50)->d(0)->MLP(26)->
Fonte: Autor
119
Fonte: Autor
120
Fonte: Autor
121
Fonte: Autor
122
Fonte: Autor
123
Fonte: Autor
124
Fonte: Autor
125
Fonte: Autor
126
Fonte: Autor
127
Fonte: Autor
128
Fonte: Autor
129
Fonte: Autor
130
2. Clima, Óbitos
Figura 127 - Teste Valor Real vs Predito e MAPE (BR Resenha, Clima, Óbitos)
Fonte: Autor
131
3. Clima, IBOV
Figura 128 - Teste Valor Real vs Predito e MAPE (BR Resenha, Clima, IBOV )
Fonte: Autor
132
Fonte: Autor
133
5. Clima, IPCA
Figura 130 - Teste Valor Real vs Predito e MAPE (BR Resenha, Clima, IPCA)
Fonte: Autor
134
Fonte: Autor
135
Fonte: Autor
136
Fonte: Autor
137
Fonte: Autor
138
Fonte: Autor
139
Fonte: Autor
140
Fonte: Autor
141
Fonte: Autor
142
Fonte: Autor
143
Fonte: Autor
144
Fonte: Autor
145
https://github.com/lvb86/PD_LSTM_GA/
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/20
04_2021_resenha_EPE.ipynb
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
df['Setor'] = Setor
df.Ano = df.Ano.astype(int)
df.Total = df.Total.astype(float)
df.Norte = df.Norte.astype(float)
df.Nordeste = df.Nordeste.astype(float)
df.Sudeste = df.Sudeste.astype(float)
df.Sul = df.Sul.astype(float)
df.CentoOeste = df.CentoOeste.astype(float)
for e, i in enumerate(lista_setor):
plt.figure(figsize=(10,8))
sns.lineplot(data = dfEPE.query(f'Setor == "{i}"'),x = 'Mes', y =
'Total', hue = 'Ano' )
plt.title(i, fontsize = 17)
dfEPE.to_csv('/tmp/ResenhaEPE.csv', index=False)
Climáticos
"""BR_Clima_2013_2020.ipynb
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/BR
_Clima_2013_2020.ipynb
##Declarações
"""
stl = style.available
# %matplotlib inline
swap = '/tmp/'
prefGo = 'https://drive.google.com/u/0/uc?export=download&id='
urlINMET = prefGo + '1FNrp311pEegFczI7NWCCXqG5BVPSHd6e'
mes =
['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']
mesN = [1,2,3,4,5,6,7,8,9,10,11,12]
# Definições de estilo
if 1==1: #tema Claro para artigo retrato
DefPalette = palettes[13] #13 Dark2
DefPaletteHist = 'rocket'
DefStyle = stl[15] #15 Seaborn-Darkgrid
DefSize = (10,6) #(17,6)
DefGrid = ('-')
## Dados INMET
"""
#Adaptado de
#https://svaderia.github.io/articles/downloading-and-unzipping-a-zipfile/
#zip.infolist()
listINMET = zip.namelist()
zip.namelist()[0]
zip.namelist()[1]
pd.read_csv(zip.open(zip.namelist()[1]),encoding='UTF-8', skiprows=9,
sep=';',parse_dates=True, decimal=',').head(3)
pd.read_csv(zip.open(zip.namelist()[1]),encoding='UTF-8', nrows=8,
sep=';',parse_dates=True, decimal=',').head(3)
zip.namelist()[1][-32:-28]
climaD.head(3)
elif e ==1:
climaH = pd.read_csv(zip.open(i), encoding='UTF-8', nrows=8, sep=':
',
parse_dates=True, decimal=',').T
header = climaH.iloc[0]
climaH.columns = header
climaH = climaH[1:]
else:
climaH2 = pd.read_csv(zip.open(i), encoding='UTF-8', nrows=8,
sep=': ',
parse_dates=True, decimal=',').T
climaH2.columns = header
climaH2 = climaH2[1:]
climaH = climaH.append(climaH2)
climaH.shape
150
climaH.head(3)
climaH.Situacao.value_counts()
climaH = climaH.reset_index().set_index('Codigo
Estacao').rename(columns={'index':'Cidade','Codigo Estacao':'origem'})
climaH.head(3)
climaD = climaD.fillna(method='ffill')
climaD.head(3)
colunasNomes = {
'Data Medicao':'data',
'NUMERO DE DIAS COM PRECIP. PLUV, MENSAL
(AUT)(número)':'Dias_com_precip',
'PRECIPITACAO TOTAL, MENSAL (AUT)(mm)':'precipitacao',
'PRESSAO ATMOSFERICA, MEDIA MENSAL (AUT)(mB)':'pressao',
'TEMPERATURA MEDIA, MENSAL (AUT)(°C)':'temperatura',
'VENTO, VELOCIDADE MAXIMA MENSAL (AUT)(m/s)':'vento_max',
'VENTO, VELOCIDADE MEDIA MENSAL (AUT)(m/s)':'vento_med',
'Unnamed: 7':'un',
'origem':'origem'
}
climaD.rename(columns=colunasNomes, inplace = True)
climaD.drop(columns=['un'], inplace = True)
climaD.columns
#Cabeçalhos
climaH.head(3)
clima.head(3)
clima.Situacao.value_counts()
parametros = climaD.columns[1:-1]
parametros
clima[['data','temperatura']].groupby('data').mean()
Mediatemperatura = clima[['data','temperatura']].groupby('data').mean()
Mediatemperatura.rename(columns={'temperatura':('temperatura','media')},
inplace = True)
MediaDias_com_precip =
clima[['data','Dias_com_precip']].groupby('data').mean()
MediaDias_com_precip.rename(columns={'Dias_com_precip':('Dias_com_precip','
media')}, inplace = True)
Mediaprecipitacao = clima[['data','precipitacao']].groupby('data').mean()
Mediaprecipitacao.rename(columns={'precipitacao':('precipitacao','media')},
inplace = True)
Mediapressao = clima[['data','pressao']].groupby('data').mean()
151
Mediapressao.rename(columns={'pressao':('pressao','media')}, inplace =
True)
Mediavento_max = clima[['data','vento_max']].groupby('data').mean()
Mediavento_max.rename(columns={'vento_max':('vento_max','media')}, inplace
= True)
Mediavento_med = clima[['data','vento_med']].groupby('data').mean()
Mediavento_med.rename(columns={'vento_med':('vento_med','media')}, inplace
= True)
clima_med=clima[['data','Cidade',*parametros]].groupby(['data','Cidade']).m
ean()
#clima[['data','temperatura','Cidade']].pivot(['Cidade'])
#.groupby(['data']).mean()#.pivot('data','Cidade').head(3)
climaPivot =
clima_med.reset_index()[['data','temperatura','Cidade']].pivot('data','Cida
de')
climaPivot = pd.merge(climaPivot, Mediatemperatura, right_on='data',
left_on='data')
climaPivot2 =
clima_med.reset_index()[['data','Dias_com_precip','Cidade']].pivot('data','
Cidade')
climaPivot2 = pd.merge(climaPivot2, MediaDias_com_precip, right_on='data',
left_on='data')
climaPivot = pd.merge(climaPivot, climaPivot2, right_on='data',
left_on='data')
climaPivot2 =
clima_med.reset_index()[['data','precipitacao','Cidade']].pivot('data','Cid
ade')
climaPivot2 = pd.merge(climaPivot2, Mediaprecipitacao, right_on='data',
left_on='data')
climaPivot = pd.merge(climaPivot, climaPivot2, right_on='data',
left_on='data')
climaPivot2 =
clima_med.reset_index()[['data','pressao','Cidade']].pivot('data','Cidade')
climaPivot2 = pd.merge(climaPivot2, Mediapressao, right_on='data',
left_on='data')
climaPivot = pd.merge(climaPivot, climaPivot2, right_on='data',
left_on='data')
climaPivot2 =
clima_med.reset_index()[['data','vento_max','Cidade']].pivot('data','Cidade
')
climaPivot2 = pd.merge(climaPivot2, Mediavento_max, right_on='data',
left_on='data')
climaPivot = pd.merge(climaPivot, climaPivot2, right_on='data',
left_on='data')
climaPivot2 =
clima_med.reset_index()[['data','vento_med','Cidade']].pivot('data','Cidade
')
climaPivot2 = pd.merge(climaPivot2, Mediavento_med, right_on='data',
left_on='data')
climaPivot = pd.merge(climaPivot, climaPivot2, right_on='data',
left_on='data')
climaPivot.head()
152
def analise_correlacao(par):
'''
Fitra prarâmetro no data frame para gerar mapa de correlação e ranking
par: entrada de parâmento
return mapa de correlação e ranking
'''
display(par)
df = climaPivot[par]
#display(df.head())
#display(df.corr())
plt.figure(figsize=(30,30))
ax = sns.heatmap(df.corr(),cmap="YlGnBu", annot=True)
plt.title('Correlação Cruzada de '+ par,fontsize=20,y=1.10)
plt.show();
ranking = climaPivot[par].corr().sum()
ranking.sort_values(ascending=False, inplace=True)
rangingCorrMed = ranking/len(ranking)
#sns.barplot(rangingCorrMed.reset_index())
plt.figure(figsize=DefSize)
ax = rangingCorrMed[:10].plot(kind='bar')
plt.title('Ranking top 10 maiores correlações médias de '+
par,fontsize=17,y=1.05)
plt.ylim(rangingCorrMed[10],rangingCorrMed.max())
plt.show();
if 0:
for i in parametros:
analise_correlacao(i)
d = {('dt','data'): climaPivot.reset_index()['data'],
('dt','Ano'): climaPivot.reset_index()['data'].str[0:4],
('dt','Mês'): climaPivot.reset_index()['data'].str[5:7],
('dt','Ano Mês'): climaPivot.reset_index()['data'].str[0:7]}
datas = pd.DataFrame(d)
climaPivot =
pd.merge(climaPivot,datas['dt'],right_on='data',left_on=('data'))
climaPivot.rename(columns={'Ano':('dt','Ano'),'Mês':('dt','Mês'),'Ano
Mês':('dt','Ano Mês')}, inplace = True)
climaPivot.head()
len(parametros)
climaPivot.sample(3)
for i in range(0,len(parametros)):
perfil_medio_clima(i, 'Perfil Médio de ', ' no BR')
"""##Juntando DF"""
climaPivot.sample(5)
('precipitacao','media'),('pressao','media'),('temperatura','media'),
('vento_max','media'),('vento_med','media')]].reset_index()
VarClima = dfClimaMed.corr().columns
dfClimaMed.corr()
sns.set_theme()
style.use(DefStyle) #4
#plt.rc_context({'axes.edgecolor':'gray', 'xtick.color':'white',
'axes.titlecolor':'white','ytick.color':'white',
'figure.facecolor':'black'})
plt.figure(figsize=DefSize)
plt.title('Correlação ente as variáveis',y=1.05,fontsize = 17)
ax = sns.heatmap(dfClimaMed.corr(),cmap="YlGnBu", annot=True)
dfClimaMed['Data'] = pd.to_datetime(dfClimaMed['Data'])
dfClimaMed.head()
dfClimaMed.columns
VarClima
dfClimaMed.to_csv(swap+'BR_2013_2020_clima.csv', index=False)
154
dfClimaMed
155
IBOV
"""IBOV.ipynb
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/IB
OV.ipynb
stl = style.available
# %matplotlib inline
prefGo = 'https://docs.google.com/uc?export=download&id='
urlibov = prefGo + '1S2SQ98qk3V52LnYde04QR2k-X8VhZ_n6'
mes =
['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']
mesN = [1,2,3,4,5,6,7,8,9,10,11,12]
# Definições de estilo
if 1==1: #tema Claro para artigo retrato
DefPalette = palettes[13] #13 Dark2
DefPaletteHist = 'rocket'
DefStyle = stl[15] #15 Seaborn-Darkgrid
DefSize = (10,6) #(17,6)
DefGrid = ('-')
ibov2013_2021
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ibov2013_2021, x= ibov2013_2021.index.month, y='ibov',
hue=ibov2013_2021.index.year)
ibov.index
157
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ibov.reset_index()[-60:], x= ibov.index[-60:],
y='ibov')#, hue=ibcbr.index.year)
decomposicao = seasonal_decompose(ibov2013_2021.ibov)
decomposicao.plot()
plt.gcf().set_size_inches(DefSize)
plt.show();
decomposicao = seasonal_decompose(ibov2013_2021.ibov,
model='multiplicative')
sns.set_theme()
style.use(DefStyle)
ax = decomposicao.plot()
plt.gcf().set_size_inches(DefSize)
plt.show();
ax = plot_acf(ibov.ibov,lags=60);
style.use(DefStyle)
#plt.rc_context({'axes.edgecolor':'gray', 'xtick.color':'white',
'ytick.color':'white', 'figure.facecolor':'black'})
IBCBR
"""ibcBR_2013_2021.ipynb
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/ib
cBR_2013_2021.ipynb
stl = style.available
# %matplotlib inline
prefGo = 'https://docs.google.com/uc?export=download&id='
urlibc = prefGo + '1QrbgeR7TyHbcNx3l-ke2RD33kn0p0BgY'
mes =
['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']
mesN = [1,2,3,4,5,6,7,8,9,10,11,12]
# Definições de estilo
if 1==1: #tema Claro para artigo retrato
DefPalette = palettes[13] #13 Dark2
DefPaletteHist = 'rocket'
DefStyle = stl[15] #15 Seaborn-Darkgrid
DefSize = (10,6) #(17,6)
DefGrid = ('-')
ibcbr.head(12).index.month
ibcbr2013_2021.to_csv('/tmp/ibcbr2013_2021.csv',index= False)
plt.figure(figsize=(16,10))
sns.lineplot(data = ibcbr2013_2021, x= ibcbr2013_2021.index.month,
y='valor', hue=ibcbr2013_2021.index.year)
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ibcbr[-24:], x= 'data', y='valor')#,
hue=ibcbr.index.year)
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ibcbr2013_2021[0:12], x=
ibcbr2013_2021.index.month[0:12], y='valor')#,
hue=ibcbr2013_2018.index.year)
160
ibcbr2013_2021
plt.figure(figsize=(16,10))
sns.lineplot(data = ibcbr2016_2021, x= ibcbr2016_2021.index.month,
y='valor', hue=ibcbr2016_2021.index.year)
ibcbr2016_2021
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(ibcbr2016_2021.reset_index().data,ibcbr2016_2021.reset_index()
.valor, palette=DefPalette)
decomposicao = seasonal_decompose(ibcbr2013_2021)
decomposicao.plot()
plt.gcf().set_size_inches(DefSize)
plt.show();
plt.show();
ax = plot_acf(ibcbr,lags=60);
style.use(DefStyle)
#plt.rc_context({'axes.edgecolor':'gray', 'xtick.color':'white',
'ytick.color':'white', 'figure.facecolor':'black'})
IPCA
"""IPCA.ipynb
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/IP
CA.ipynb
stl = style.available
# %matplotlib inline
prefGo = 'https://docs.google.com/uc?export=download&id='
urlipca = prefGo + '1l6wRFAprymsQoVoNqAvv1g2EMN2tmVMa'
mes =
['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']
mesN = [1,2,3,4,5,6,7,8,9,10,11,12]
# Definições de estilo
if 1==1: #tema Claro para artigo retrato
DefPalette = palettes[13] #13 Dark2
DefPaletteHist = 'rocket'
DefStyle = stl[15] #15 Seaborn-Darkgrid
DefSize = (10,6) #(17,6)
DefGrid = ('-')
ipca
ipca2013_2021.head()
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ipca2013_2021, x= ipca2013_2021.index.month, y='ipca',
hue=ipca2013_2021.index.year)
ipca.index
plt.figure(figsize=(16,10))
sns.set_theme()
sns.lineplot(data = ipca.reset_index()[-60:], x= ipca.index[-60:],
y='ipca')#, hue=ibcbr.index.year)
decomposicao = seasonal_decompose(ipca2013_2021.ipca)
163
decomposicao.plot()
plt.gcf().set_size_inches(DefSize)
plt.show();
decomposicao = seasonal_decompose(ipca2013_2021.ipca,
model='multiplicative')
sns.set_theme()
style.use(DefStyle)
ax = decomposicao.plot()
plt.gcf().set_size_inches(DefSize)
plt.show();
ax = plot_acf(ipca.ipca,lags=60);
style.use(DefStyle)
#plt.rc_context({'axes.edgecolor':'gray', 'xtick.color':'white',
'ytick.color':'white', 'figure.facecolor':'black'})
Óbitos
"""Obitos_Tabnet_2013_2021.ipynb
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/Ob
itos_Tabnet_2013_2021.ipynb
"""
stl = style.available
# %matplotlib inline
prefGo = 'https://docs.google.com/uc?export=download&id='
urlTabnet = prefGo + '1z1vn0D9Efnl-wRO_tYDZafZhLGRrPwc0'
mes =
['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']
mesN = [1,2,3,4,5,6,7,8,9,10,11,12]
# Definições de estilo
if 1==1: #tema Claro para artigo retrato
DefPalette = palettes[13] #13 Dark2
DefPaletteHist = 'rocket'
DefStyle = stl[15] #15 Seaborn-Darkgrid
DefSize = (10,6) #(17,6)
DefGrid = ('-')
tabnet.head()
tabnet['Mês'] = tabnet['Mês'].str.strip()
tabnet['mm'] = tabnet['Mês'].map(mapmes)
tabnet.mm.unique()
plt.figure(figsize = (16,10))
sns.lineplot(data=tabnet, x = tabnet.index, y=tabnet.Total)
166
plt.figure(figsize = (8,6))
ax = sns.lineplot(data=tabnet, x = tabnet.Ano_mes, y=tabnet.Total)
ax.set_xticks(ax.get_xticks()[::12])
plt.xticks(rotation = 45)
plt.xlabel('Ano Mês')
plt.ylabel('Total de Óbitos')
plt.show();
plt.figure(figsize = (16,10))
sns.lineplot(data=tabnet, x = tabnet.mm, y=tabnet.Total, hue=tabnet.Ano)
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/Te
stes_de_Hiper_Par%C3%A2metros.ipynb
#Pesquisa de Hiperparâmetros
Na MLP da Biblioteca Scikit-learn
#Declarações Globais
"""
urldfCC =
'https://raw.githubusercontent.com/lvb86/MLPr_GA/main/swap/dfConsumoClima2.
csv'
df = pd.read_csv(urldfCC)
d = df.iloc[:,2:-3]
d.head()
"""Funções Compartilhadas"""
plt.figure(figsize=(12,8))
g= sns.barplot(x=x,y=y, palette='rocket')
for i in range(len(x)):
g.text(i,y[i]+0.001, round(y[i],3), color='black', ha="center",
fontsize=15)
plt.xticks(rotation = rot, fontsize=15)
#plt.ylim(0,1.1)
plt.ylabel('MAPE')
plt.xlabel(Xlabel)
plt.show();
"""#Testes
## Melhor configuração
"""
#hidden_layer_sizes = (8,16,32,4)
hidden_layer_sizes = (2,3,59,38)
activation='relu'
random_state=1
max_iter=100_000
alpha = 0.0001
learning_rate_init = 0.001
shuffle = True
beta_1 = 0.94
beta_2 = 0.999
epsilon = 0.000_000_000_1
n_iter_no_change=1000
solver='adam'
verbose = False
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.get_params()
"""## Estrutura"""
dic_param = {
1:(2,),
2:(8, 4),
3:(8, 4, 2),
4:(8, 16, 4, 2),
5:(8, 16, 8, 4, 2),
169
dic_param2 = {
1:(8,),
2:(8, 4),
3:(8, 8, 4),
4:(8, 16, 32, 4),
5:(8, 16, 32, 64, 4),
6:(8, 16, 32, 64, 128, 4),
7:(8, 16, 32, 64, 128, 256, 4),
8:(8, 16, 32, 64, 128, 256, 512, 4),
9:(8, 16, 32, 64, 128, 256, 512, 1024, 4),
10:(8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4)}
dic_param3 = {
1:(8,16,32,2),
2:(8,32,16,2),
3:(8,32,16,4),
4:(8,32,64,2),
5:(8,64,32,2),
6:(8,32,64,4),
7:(8,64,32,4)}
mape = []
Lparam = []
for i in dic_param3:
print(dic_param3[i])
p = dic_param3[i]
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes= p,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'hidden_layer_sizes', 30)
"""resultados agrupados"""
170
url =
'https://github.com/lvb86/MLPr_GA/blob/main/swap/ResultadosRede.xlsx?raw=tr
ue'
top10=pd.read_excel(url, ).iloc[0:10,:]
top10
graf_bar(top10.Estrutura,top10.MAPE,'Estrutura',90)
"""##Função de ativação"""
param = ['relu','identity','tanh','logistic']
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=p,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
print('mape','|',m)
graf_bar(param,mape,'Função de ativação',0)
"""##Solver"""
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
171
n_iter_no_change=n_iter_no_change,
solver=p,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
print('mape','|',m)
graf_bar(param,mape,'solver', 0)
"""##Alpha"""
param = [1,0.1,0.01,0.001,0.0001,0.00001]
Lparam = []
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = p,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'alpha', 0)
"""##Learning Rate"""
learning_rate_init = p,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'learning_rate_init', 30)
"""##Shuffle"""
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'suffle', 0)
"""##Beta 1 """
param = [0.001, 0.01, 0.1, 0.2, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99]
Lparam = []
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
173
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = p,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'beta_1', 0)
"""##Beta 2"""
param = [0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 0.995, 0.999, 0.9999]
Lparam = []
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = p,
epsilon = epsilon,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'beta_2', 0)
Lparam = []
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = p,
n_iter_no_change=n_iter_no_change,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'epsilon', 0)
param = [1,10,20,30,40,50,70,100,200,1000,10000,100000]
Lparam = []
mape = []
for e, p in enumerate(param):
pipe_mlp = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes=
hidden_layer_sizes,
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=p,
solver=solver,
verbose = verbose
)
)
pipe_mlp.fit(X_train, y_train)
y_pred = pipe_mlp.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred)
mape.append(m)
Lparam.append(str(p))
print('mape','|',m)
graf_bar(Lparam,mape,'n_iter_no_change', 0)
175
"""#Comparativo
##MLP
"""
pipe_mlp1 = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes= (8,16,32,4),
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=p,
solver=solver,
verbose = verbose
)
)
pipe_mlp1.fit(X_train, y_train)
y_pred1 = pipe_mlp1.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred1)
print('mape','|',m)
"""##MLP+GA"""
pipe_mlp2 = make_pipeline(StandardScaler(),
#PCA(n_components=i),
MLPRegressor(hidden_layer_sizes= (2,3,59,38),
activation=activation,
random_state=random_state,
max_iter=max_iter,
alpha = alpha,
learning_rate_init =
learning_rate_init,
shuffle = shuffle,
beta_1 = beta_1,
beta_2 = beta_2,
epsilon = epsilon,
n_iter_no_change=p,
solver=solver,
verbose = verbose
)
)
pipe_mlp2.fit(X_train, y_train)
y_pred2 = pipe_mlp2.predict(X_test)
m = mean_absolute_percentage_error(y_test,y_pred2)
print('mape','|',m)
"""##Graficos Comparativos"""
df['ConsumoMLP'] = 0
df['ConsumoMLP2'] = 0
y_pred_serie = (np.zeros(60)*np.nan).tolist()+y_pred.tolist()
y_pred2_serie = (np.zeros(60)*np.nan).tolist()+y_pred2.tolist()
df['ConsumoMLP'] = y_pred_serie
176
df['ConsumoMLP2'] = y_pred2_serie
df
dcom.info()
sns.set_theme()
#style.use(DefStyle)
plt.figure(figsize = (16,10))
plt.legend()
plt.grid('-')
#plt.title('Perfil de consumo Rural no RS Previsto vs Medido', fontsize=17,
y=1.05)
ax2.yaxis.set_major_formatter(ticker.FuncFormatter(formatador_de_milhares))
plt.ylabel('Consumo [MWh]')
ax2.set_xticks(ax2.get_xticks()[::3])
plt.xticks(rotation = 90, fontsize=10)
plt.show()
sns.set_theme()
#style.use(DefStyle)
plt.figure(figsize = (16,10))
plt.legend()
plt.grid('-')
#plt.title('Perfil de consumo Rural no RS Previsto vs Medido', fontsize=17,
y=1.05)
ax5.yaxis.set_major_formatter(ticker.FuncFormatter(formatador_de_milhares))
plt.ylabel('Consumo [MWh]')
ax6.set_xticks(ax6.get_xticks()[::3])
plt.xticks(rotation = 90, fontsize=10)
plt.show();
dcom2018.columns
print('MLP + GA =' ,
mean_absolute_percentage_error(dcom2018['Consumo'],dcom2018['ConsumoMLP2'])
)
print('MLP =' ,
mean_absolute_percentage_error(dcom2018['Consumo'],dcom2018['ConsumoMLP']))
print('Fuzzy =' ,
mean_absolute_percentage_error(dcom2018['Consumo'],dcom2018['Consumo_fuzzy'
]))
print('Rlin =' ,
mean_absolute_percentage_error(dcom2018['Consumo'],dcom2018['Rlin']))
print('Médio =' ,
mean_absolute_percentage_error(dcom2018['Consumo'],dcom2018['Consumo
Médio']))
"""#fim"""
178
https://colab.research.google.com/github/lvb86/PD_LSTM_GA/blob/main/code/LS
TM_GEN_e32_p16_BR_res_ibcbr_ibov_obitos_ipca_2015_2020.ipynb
Aplicado a Scenário:
* BR padrão 32 épocas, pop = 16
* Período 2015-2020
##_Entradas_
* IBCBR
* IBOV
* IPCA
* Obitos
* Clima
* Consumo Resenha EPE:
- Comercial
- Industrial
- Residencial
- Outros
##Declarações Globais
"""
if 0:
from google.colab import drive
drive.mount('/content/drive')
seed = 170696
sns.set()
sns.set_theme()
"""#### Path"""
path = '/tmp/'
patha = path + 'arcaBR_sn/'
pathb = patha + 'bkp/'
urla = patha + 'arca.csv'
prefGo = 'https://docs.google.com/uc?export=download&id='
def imports():
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
import pandas as pd
import seaborn as sns
import tensorflow as tf
import os
import glob
import shutil
import random as rn
import math
seed = 170696
sns.set()
sns.set_theme()
180
session_conf = tf.compat.v1.ConfigProto(intra_op_parallelism_threads=1,
inter_op_parallelism_threads=1)
from keras import backend as K
tf.compat.v1.set_random_seed(seed)
sess = tf.compat.v1.Session(graph=tf.compat.v1.get_default_graph(),
config=session_conf)
K.set_session(sess)
dt_seg_now = datetime.now().strftime("%S")
#print("\t\tSEED =", dt_seg_now)
nseed = int(dt_seg_now)
os.environ['PYTHONHASHSEED'] = str(nseed)
np.random.seed(nseed)
rn.seed(nseed)
if verbose: print("\t\tSEED =", dt_seg_now)
"""## Dados"""
anoIni = 2015
anoFim = 2020
ibov.info()
pd.read_csv(urlEPE)
dfEPE = pd.read_csv(urlEPE)
dfEPE = dfEPE[(dfEPE.Ano >= anoIni) & (dfEPE.Ano <= anoFim)]
dfEPE = dfEPE.pivot(index = ['Ano Mês','Mes'], columns='Setor',values =
'Total')
dfEPE['Consumo'] = dfEPE.Comercial + dfEPE.Residencial + dfEPE.Comercial +
dfEPE.Outros
df = dfEPE.reset_index()
df = pd.merge(df,ibcbr[['Ano Mês','ibcbr']],left_on='Ano Mês',right_on='Ano
Mês')
df = pd.merge(df,ibov[['Ano Mês','ibov']],left_on='Ano Mês',right_on='Ano
Mês')
df = pd.merge(df,obtosBR[['Ano Mês','Obitos']],left_on='Ano
Mês',right_on='Ano Mês')
df = pd.merge(df,ipca[['Ano Mês','ipca']],left_on='Ano Mês',right_on='Ano
Mês')
df = pd.merge(df,clima.reset_index()[['Ano Mês','Dias com
Precipitação','Precipitação', 'Pressão', 'Temperatura', 'Vento Máx', 'Vento
Méd' ]], left_on='Ano Mês',right_on='Ano Mês')
df.head(3)
df.columns
df['mes_sin'] = np.sin(df['Mes']*2*np.pi/12)
df['mes_cos'] = np.cos(df['Mes']*2*np.pi/12)
d = df.drop(columns=['Ano Mês', 'Mes']).reset_index()
Ycolumns = ['Consumo', 'Comercial', 'Industrial', 'Residencial', 'Outros']
Xcolumns = [*{*d.columns.to_list()}-{*Ycolumns,'index','level_0'}]
print('X\n',len(Xcolumns),'\n', Xcolumns)
print('Y\n',len(Ycolumns),'\n', Ycolumns)
"""## Funções
df.shape[0]
182
def TrainTestData(col_i):
lin = df.shape[0]
lin_train = lin - 12
X = d[Xcolumns]
y = d[Ycolumns]
y = y.iloc[:,col_i]
# Different scaler for input and output
scaler_x = MinMaxScaler(feature_range = (0,1))
scaler_y = MinMaxScaler(feature_range = (0,1))
#print(2)
# Fit the scaler using available training data
input_scaler = scaler_x.fit(X)
X_norm = input_scaler.transform(X)
#print('y_shape= ',y.shape)
#print('y_shape= ',len(y.shape))
if len(y.shape) == 1:
# print('..reshape')
output_scaler = scaler_y.fit(y.to_numpy().reshape(-1,1))
y_norm = output_scaler.transform(y.to_numpy().reshape(-1,1))
else:
output_scaler = scaler_y.fit(y)
y_norm = output_scaler.transform(y)
X_train = X_norm[:lin_train]
y_train = y_norm[:lin_train]
X_test = X_norm[lin_train:]
y_test = y_norm[lin_train:]
y_real = y[lin_train:]
X_train = X_train.reshape(X_train.shape[0], 1, X_train.shape[1])
X_test = X_test.reshape(X_test.shape[0], 1, X_test.shape[1])
shape_in = X_train.shape[2]
shape_out = y_train.shape[1]
def TrainTestData_old(verbose=False):
lin = df.shape[0]
lin_train = lin - 12
X = d[Xcolumns]
y = d[Ycolumns]
# Different scaler for input and output
scaler_x = MinMaxScaler(feature_range = (0,1))
scaler_y = MinMaxScaler(feature_range = (0,1))
X_train = X_norm[:lin_train]
183
y_train = y_norm[:lin_train]
X_test = X_norm[lin_train:]
y_test = y_norm[lin_train:]
y_real = y[lin_train:]
shape_in = X_train.shape[2]
shape_out = y_train.shape[1]
return
X,y,input_scaler,output_scaler,X_train,y_train,X_test,y_test,y_real,shape_i
n, shape_out
"""###Genéticas
pop0 = np.random.randint(
limites[0], limites[1], size=(pop_tamanho, n_genes)
)
pop=[]
for e, i in enumerate(pop0):
if np.sum(i) == 0:
n = np.random.randint(limites[0]+1, limites[1], size=(1,
n_genes))
#print(e,i,n)
pop.append(n)
else:
pop.append(i)
return pop
"""####Função de aptidão"""
'''
dic_bl = {0: 'LSTM', 1:'BILSTM'}
desc = '->'
184
bl_list = []
drop_list = []
unit_list = []
Lini = 0
Lcount = 0
for i in range(7,13):
if chave[i] >0:
ini = i-6
break
for i in range(7,13):
if chave[i] >0:
Lcount +=1
if verbose: print(f'\tN Layers = {Lcount}')
else: print('.',sep='',end='')
for i in range(2):
if chave[i] % 2 == 0:
bl_list.append(1)
else:
bl_list.append(0)
for i in range(2,7):
if chave[i] ==0:
drop_list.append(0)
else:
if chave[i] % 2 == 0:
drop_list.append(0.2)
else:
drop_list.append(0.1)
185
for i in range(7,13):
unit_list.append(chave[i])
else: #MLP
model.add(tf.keras.layers.Dense(units = i,
activation=tf.nn.relu) )
if e < 5:
#Dropout
model.add(tf.keras.layers.Dropout(drop_list[e], seed =
seed) )
model.add(tf.keras.layers.Dense(shape_out))
return model
with tf.device(':CPU:0'):
model.compile(optimizer = 'adam',loss='mse',
metrics=['accuracy','mape'])
early_stop = keras.callbacks.EarlyStopping(monitor = 'loss',
patience = 10)
model.fit( x=X_train,
y=y_train,
batch_size=None,
epochs=10000,
verbose=False,
callbacks=[early_stop],
validation_split=0.0,
#validation_data=(X_test,y_test),
shuffle=False,
186
class_weight=None,
sample_weight=None,
initial_epoch=0,
steps_per_epoch=19,
validation_steps=1,
validation_batch_size=None,
validation_freq=1,
max_queue_size=10,
workers=1,
use_multiprocessing=False)
y_pred_norm = model.predict(X_test)
if shape_out ==1:
y_pred =
output_scaler.inverse_transform(y_pred_norm.ravel().reshape(-1, 1))
else:
y_pred =
output_scaler.inverse_transform(y_pred_norm.reshape(12,shape_out))
mape = mean_absolute_percentage_error(y_real,y_pred)
apti = 1-mape
if verbose: print('\t\t',pp)
else: print('.',sep='',end='')
return pp
"""#### Cruzamento"""
if verbose:
print('\t\tpar --', casal,'------')
print('\t\tp:',p1,populacao[p1]) #p1
print('\t\tp:',p2,populacao[p2]) #p2
else: print('.',sep='',end='')
s1=np.ones(ng)
while(s1.sum()==ng or s1.sum()==0): # garantia de que havera ao menos
s1=np.random.choice([0,1],ng) # 1 cruzamento
if verbose: print('\t\txxx ', s1)
else: print('.',sep='',end='')
for i, b in enumerate(s1):
#print(i,b)
if b:
#print(x[7][i])
f1.append(populacao[p1][i])
f2.append(populacao[p2][i])
else:
#print(x[9][i])
f1.append(populacao[p2][i])
f2.append(populacao[p1][i])
if verbose:
print('\t\tf1 ',f1)
print('\t\tf2 ',f2)
else: print('.',sep='',end='')
return np.array(f1),np.array(f2)
"""#### Mutação"""
#mutacao
def mutacao(original, proba_mut, ng, verbose= False):
'''
apartir de um individuo original será gerado 1 individuo mutante
s1=np.ones(ng)
while(s1.sum()==0): # garantia de que havera ao menos
s1=np.random.choice([0,1],ng,p=[1-proba_mut,proba_mut]) # 1
mutação
if verbose: print('\t\txxx ', s1)
else: print('.',sep='',end='')
for i, b in enumerate(s1):
#print(i,b)
if b:
188
#print(x[7][i])
mutante.append(gm[i])
else:
mutante.append(original[i])
if verbose: print('\t\tmut ',mutante)
else: print('.',sep='',end='')
return np.array(mutante)
'''
for index, it in enumerate(_lista):
#print(index,it,_item, all(it==_item))
if (all(it==_item)):
return True, index
return False, False
def salva_arca(_ep,idtest):
now = datetime.now().strftime('_%y_%m_%d-%H_%M_')
url = patha + 'arca' +str(idtest)+ now + str(_ep) + '.csv'
#arca = pd.DataFrame([arca_gen,arca_mape,arca_apt]).T
arca = pd.DataFrame(dic_arca).T.iloc[:,-3:]
arca.columns = ['gen','mape','apt']
arca.apt = 1-arca.mape #correção de aptidão relativa para geral
arca.to_csv(url,index=False)
def recupera_arca():
'''
Recupera dados de testes passados
arca_gen = []
for e, arc_g in enumerate(arca_gen_str):
arca_gen.append(gene_str2numpy(arc_g))
print(len(arca_gen))
dic_arca = {} # Cria dicionário vazio. # set() = conjunto vazio
dic_arca_i = {}
for e, i in enumerate(arca_gen):
dic_arca[tuple(i)] = [e,i,arca_mape[e],arca_apt[e]]
dic_arca_i[e] = i
#len(arca_gen) == len(arca_mape)
def gene_str2numpy(_str):
'''
189
for i in range(len(indice)-1):
n_str =_str[indice[i]+1:indice[i+1]]
arn.append(int(n_str.strip()))
return np.array(arn)
def salva_resultado(_ep,_res,_mut,_tempo,_pop,_pop_r,_pop_c,idtest):
now = datetime.now().strftime('_%y_%m_%d-%H_%M_')
url = path + 'resultado' +str(idtest)+ now + str(_ep) + '.csv'
result = pd.DataFrame([_res,_mut,_tempo,_pop,_pop_r,_pop_c]).T
result.columns =
['Mape','Mutacao','Tempo','Populacao','Pop_Recuperada','Pop_Calculada']
result.to_csv(url,index = False)
def atualiza_arca(_bol):
if _bol:
os.chdir(patha)
extension = 'csv'
all_filenames = [i for i in
glob.glob('arca*.{}'.format(extension))]
if len(all_filenames):
now = datetime.now().strftime('%y_%m_%d-%H_%M')
url = pathb + 'arca_bkp_' + now + '.csv'
if os.path.exists(patha+'arca.csv'):
pd.read_csv(patha+'arca.csv').to_csv(url)
#combine all files in the list
combined = pd.concat([pd.read_csv(f) for f in all_filenames ])
filtred =
combined[['gen','mape','apt']].sort_values('mape').drop_duplicates()
#export to csv
filtred.to_csv("arca.csv", index=False, encoding='utf-8-sig')
# move arquivos para o bkp
for f in all_filenames:
if f !='arca.csv':
shutil.move(patha+f,pathb+f)
print(f)
#https://www.freecodecamp.org/news/how-to-combine-multiple-csv-files-with-
8-lines-of-code-265183e0854/
#https://datatofish.com/move-file-python/
if 0:
dfa = pd.read_csv(patha + 'arca.csv')
dfa['len'] = dfa['gen'].apply(lambda x: len(x))
#dfa['len'].count_values()
dfb=dfa[dfa['len'] == 40]
dfb.drop(['len'], axis =1 ,inplace = True)
dfb.sort_values('mape').to_csv(patha + 'arca.csv', index = False)
pd.read_csv(patha + 'arca.csv')
def df_arca_hist(df):
'''
190
return arca_hist[arca_hist.dim != 0]
"""###Relatórios e Medidas"""
def relatorio_parcial(ep,
count_parada,
arca_gen,
ar_mape_gen,
ar_mape_min,
ar_mape_ind,
ge_mape_gen,
ge_mape_min,
ge_mape_ind,
list_tdiff,
list_t_pop,
list_t_pop_c,
list_t_pop_r,
list_mutacao,
max_comb,
res,
teste_mape
):
print('__________________RELATÓRIO
PARCIAL________________________________'
,'\n\t\t Geração =', ep
,'\n\t\t Parado =', count_parada
,'\n\t\t Códigos na arca =', len(arca_gen)
,'\n\t\t % da população avaliada =',
f'{(len(arca_gen)/max_comb)*100:.5f} %'
191
sns.lineplot(ax=axs[0,0],x=range(len(res)),y=res)
axs[0,0].set_title('MAPE mínimo por Geração')
axs[0,0].set_ylabel('MAPE')
#axs[0,0].set_xlabel('Geração')
sns.lineplot(ax=axs[1,0],x=range(len(list_mutacao)),y=list_mutacao)
axs[1,0].set_title('Evolução do Fator de mutação')
axs[1,0].set_ylabel('Fator de mutação')
#axs[1,0].set_xlabel('Geração')
sns.lineplot(ax=axs[0,1],x=range(len(list_t_pop)),y=list_t_pop, label =
'total')
sns.lineplot(ax=axs[0,1],x=range(len(list_t_pop_c)),y=list_t_pop_c,
label = 'calculada')
sns.lineplot(ax=axs[0,1],x=range(len(list_t_pop_r)),y=list_t_pop_r,
label = 'recuperada')
axs[0,1].set_title('Evolução tamanho da população')
axs[0,1].set_ylabel('Indivíduos')
#axs[0,1].set_xlabel('Geração')
sns.lineplot(ax=axs[1,1],x=range(len(list_tdiff)),y=list_tdiff)
sns.lineplot(ax=axs[1,1],x=range(len(list_tdiff)),y=np.mean(list_tdiff))
axs[1,1].set_title('Perfil de tempo por iteração')
axs[1,1].set_ylabel('tempo [min]')
#axs[1,1].set_xlabel('Geração')
192
sns.histplot(ax=axs[2,0],data=teste_mape, kde=True)
axs[2,0].set_title('Distribuíção de erro por genoma teste')
list_t_pop_a = []
list_t_pop_ca = []
list_t_pop_ra = []
for e,i in enumerate(list_t_pop_c):
list_t_pop_a.append(sum(list_t_pop[:e+1]))
list_t_pop_ca.append(sum(list_t_pop_c[:e+1]))
list_t_pop_ra.append(sum(list_t_pop_r[:e+1]))
sns.lineplot(ax=axs[2,1],x=range(len(list_t_pop_a)),
y=list_t_pop_a,label = 'total')
sns.lineplot(ax=axs[2,1],x=range(len(list_t_pop_ca)),
y=list_t_pop_ca, label = 'calculada')
sns.lineplot(ax=axs[2,1],x=range(len(list_t_pop_ra)),
y=list_t_pop_ra,label = 'recuperada')
#sns.ecfplot(ax=axs[2,1],list_t_pop_t, label = 'indivíduos avaliados')
axs[2,1].set_title('População acumulada')
axs[2,1].set_ylabel('Indivíduos')
#arca_hist = df_arca_hist(pd.read_csv(urla))
#sns.histplot(ax=axs[2,1],data=arca_hist, kde=True)
#axs[2,1].set_title('Distribuíção de erro por genoma hist.')
def plt_consumo12(y_true,y_pred):
plt.figure(figsize=(10,8))
ax1 = sns.lineplot(x=range(1,13),y=y_true, label='Real')
ax2 = sns.lineplot(x=range(1,13),y=y_pred.ravel(), label='LSTM')
ax2.yaxis.set_major_formatter(ticker.FuncFormatter(formatador_de_milhares))
plt.legend()
plt.grid('-')
plt.ylabel('Consumo [MWh]')
#ax2.set_xticks(ax2.get_xticks()[::3])
#plt.xticks(rotation = 90, fontsize=10)
plt.show();
def plt_barras(x,y,*titulo):
plt.figure(figsize=(12,8))
sns.set_style('darkgrid')
g = sns.barplot(x=x, y=y, palette='rocket')
plt.title('MAPE por SetorN1', fontsize = 17)
for i in range(len(x)):
g.text(i,y[i]+0.001, round(y[i],3), color='black', ha="center",
fontsize=15)
plt.xticks(rotation = 90, fontsize=15)
plt.ylabel('MAPE')
#plt.xlabel('SetorN1')
plt.show()
;
def plt_perfis_de_consumo(yp):
list_mape = []
if e < 3:
s = 0
elif e < 6:
s = 1
else:
s = 2
sns.lineplot(ax=axs[s,e-s*3],x=range(1,13),y=yp[:,e]/1000, label =
'pred')
sns.lineplot(ax=axs[s,e-s*3],x=range(1,13),y=y.iloc[60:,e]/1000,
label = 'real')
axs[s,e-s*3].set_title(i)
axs[s,e-s*3].set_xlabel('')
axs[s,e-s*3].set_ylabel('')
#axs[s,e-s*3].set_ylim(0,3_000_000)
axs[s,e-s*3].set_ylim(0)
axs[s,e-s*3].set_xticks(range(0,13,2))
axs[s,e-s*3].set_xlim(1, 12)
axs[s,e-
s*3].yaxis.set_major_formatter(ticker.FuncFormatter(formatador_de_milhares)
)
mape = mean_absolute_percentage_error(y.iloc[60:,e],yp[:,e])
list_mape.append(mape)
list_mape.append(np.array(list_mape).mean())
for i in range(len(y_bars)):
g.text(i,list_mape[i]+0.001, round(list_mape[i],3),
color='black', ha="center", fontsize=15)
plt.xticks(rotation = 90, fontsize=15)
plt.ylabel('MAPE')
#plt.xlabel('SetorN1')
plt.show()
;
def plt_perfis_de_consumo2(yp):
yp = y_pred_list.T
list_mape = []
axs[s,e-s*3].set_ylabel('')
#axs[s,e-s*3].set_ylim(0,3_000_000)
axs[s,e-s*3].set_ylim(0)
axs[s,e-s*3].set_xticks(range(0,13,2))
axs[s,e-s*3].set_xlim(1, 12)
axs[s,e-
s*3].yaxis.set_major_formatter(ticker.FuncFormatter(formatador_de_milhares)
)
mape = mean_absolute_percentage_error(y.iloc[-12:,e],yp[:,e])
list_mape.append(mape)
list_mape.append(np.array(list_mape).mean())
plt.show()
;
"""###Algoritmo Genético"""
def algoritmo_genetico(
ini_pop = True ,
pop_selecao = 0 ,
recup_memo = False ,
epocas = 100 ,
pop_tamanho = 64 ,
n_genes = 13 ,
limites_genes = (0,64) ,
indice_mut = 0.2 ,
#casais = int((pop_tamanho+pop_selecao)/4) ,
max_parado = 200 ,
alvo = 0.001 ,
bool_salva_arca = False ,
verbose = False
):
'''
Parâmetros de entrada:
ini_pop # Inicializa população aleatória
pop_selecao # N melhore hist Selecionados para geração 0
recup_memo # True recupera memória de iterações passadas
epocas # total de gerações/Epocas
pop_tamanho # tamanho da inicial população
n_genes # Número de Genes
limites_genes # Limite de valores para cada Gene
indice_mut # Probaabilidade de Mutação inicial
#casais # Número de casais Progenitores
max_parado # Limite de epocas parado no mesmo erro
alvo # Erro Alvo
bol_salva_arca # Exportar resultados
verbose # Saída de fluxo
Saídas
Código Genético do melhor modelo
Valor de Erro (MAPE) do melhor modelo
'''
#----------------------------------------------------------------------
----
195
## Variáveis de Controle
casais = int((pop_tamanho+pop_selecao)/4)
arca_gen = [] # Memória genetica
arca_apt = [] # Memória de aptidão
arca_mape = [] # Memória de mape
teste_mape = []
count_parada = 0
count_pop_r = 0
count_pop_c = 0
res = []
elite = []
list_mutacao = []
list_tdiff = []
list_t_pop = []
list_t_pop_r = []
list_t_pop_c = []
novos_individuos= []
pre_selecionado = []
selecionado = []
pop = []
ep = 0
min_anterior = 1
test_comb = epocas*pop_tamanho
max_comb = ((limites_genes[1]-limites_genes[0])+1)**n_genes
if verbose:
if verbose:
print('--------------------------------------------------------
------------'
,'\n\t\t\t', len(arca_gen),'codigos recuperados'
,'\n\t\t\t', f'{(len(arca_gen)/max_comb)*100:.5f} % da
população avaliada' )
else: print('.',sep='',end='')
else:
dic_arca = {}
dic_arca_i = {}
if ini_pop:
if verbose:
print('-->Inicializa
População............................................')
else: print('.',sep='',end='')
pop = inicializa_populacao(pop_tamanho,n_genes,limites_genes)
if verbose: print('População Inicial:',pop)
else: print('.',sep='',end='')
if pop_selecao >0:
for e, i in enumerate(arca_gen):
if len(i) ==n_genes:
pre_selecionado.append(i)
if verbose: print (len(pre_selecionado),'possiveis de seleção')
else: print('.',sep='',end='')
for e, i in enumerate(pre_selecionado[0:pop_selecao]):
if verbose: print (e,i, len(i))
else: print('.',sep='',end='')
selecionado.append(i)
pop += selecionado
for ep in range(epocas):
T1 = datetime.now()
gera_mape = []
count_pop_r = 0
count_pop_c = 0
if verbose:
print('-->>epoca',ep,'-----------------------------------------
-----------')
else: print('\n--># ep.',ep,sep='',end='')
#print('Novos Individuos:',novos_individuos)
if ep > 0:
if verbose:
print('-->>>Seleção----------------------------------------
-----------')
else: print('.',sep='',end='')
for i in progenitores.ravel():
# Progenitores selecionados aleatóriamente #####
novos_individuos.append(pop[i])
if verbose: print("Progenitores", pop[i])
else: print('.',sep='',end='')
for el in range(2):
# Elite garantindo os 2 melhores da geração anterior
bol, pos = busca_item_lista(elite[el],novos_individuos)
if not bol:
if verbose: print('\t\t VIP', elite[el])
else: print('.',sep='',end='')
novos_individuos.append(elite[el])
pop = novos_individuos
novos_individuos = []
197
list_t_pop.append(len(pop))
#print('Novos Individuos:',novos_individuos)
probabilidades = []
if verbose: print('-->>>Aptidão------------------------------------
-------------------')
else: print('.',sep='',end='')
for id, individuo in enumerate(pop):
if verbose: print(ep,'#', id, individuo)
else: print('.',sep='',end='')
#bag, ibag = busca_item_lista(individuo, arca_gen)
if tuple(individuo) in dic_arca:
if verbose:
print('\t__Individuo Clone Recuperado da Arca #id:',
dic_arca[tuple(individuo)][0])
else: print('.',sep='',end='')
a = dic_arca[tuple(individuo)][3]
m = dic_arca[tuple(individuo)][2]
if verbose:
print('\t arca_apt recuperado:',a)
print('\t arca_mape recuperado:',m)
else: print('.',sep='',end='')
count_pop_r +=1
else:
m,a,yp = func_aptidao(individuo)
dic_arca[tuple(individuo)]=[len(dic_arca),individuo,m,a]
dic_arca_i[len(dic_arca_i)]=individuo
arca_gen.append(individuo)
arca_apt.append(a)
arca_mape.append(m)
count_pop_c +=1
#print(probabilidades)
if m>1:
probabilidades.append(0)
else:
probabilidades.append(1-m)
gera_mape.append(m)
#print('\t\t individuo mape',individuo,m)
#print('\t\t',gera_mape)
list_t_pop_c.append(count_pop_c)
list_t_pop_r.append(count_pop_r)
probabilidades =(np.array(probabilidades)/sum(probabilidades))
#print('\t população avaliada:', pop)
if verbose:
print('\t Probabilidades:', np.round(probabilidades,4))
print('-->>>Elite----------------------------------------------
-----------')
else: print('.',sep='',end='')
prob_elite = np.sort(probabilidades).tolist()[-2:]
elite = [ pop[probabilidades.tolist().index(prob_elite[0])],
pop[probabilidades.tolist().index(prob_elite[1])]]
if verbose:
print('\t\t Elite :', elite)
print('-->>>Progenitores---------------------------------------
-----------')
else: print('.',sep='',end='')
progenitores = selecao_de_progenitores(pop, probabilidades, casais)
if verbose:
198
print('-->>>Cruzamento-----------------------------------------
-----------')
for p in progenitores:
f1, f2 = cruzamento(p,pop, n_genes)
novos_individuos.append(f1)
novos_individuos.append(f2)
if verbose:
print('Novos Individuos F1:',f1)
print('Novos Individuos F2:',f2)
else: print('.',sep='',end='')
#print('Novos Individuos:',novos_individuos)
if verbose:
print('-->>>Mutação--------------------------------------------
-----------')
# Replicas com Mutação dos filhos
mutantes = []
for en, ori in enumerate(novos_individuos):
mu = mutacao(ori,indice_mut,n_genes)
mutantes.append(mu)
novos_individuos += mutantes
# Replicas com mutação da elite
mutantes2 = []
if verbose:
print('Novos Individuos:',novos_individuos)
else: print('.',sep='',end='')
if verbose: relatorio_parcial()
else: print('.',sep='',end='')
if bool_salva_arca: salva_arca(ep,idtest)
199
# Critérios de parada
if ge_mape_min < alvo:
print('para por atingimento do alvo')
break
if verbose: print(f'\t Min Erro Atual {ge_mape_min:.5f} x
{min_anterior:.5f} Min Erro Anterior')
else: print('.',sep='',end='')
if round(ge_mape_min,5) == round(min_anterior,5):
count_parada +=1
if count_parada > 4:
if indice_mut < 0.81:
indice_mut += 0.1
if verbose: print('Indice Mutação: ', indice_mut)
else: print('.',sep='',end='')
count_parada = 0
if indice_mut > 0.81:
indice_mut = 0.8
if ep+1 == epocas:
relatorio_parcial(ep,
count_parada,
arca_gen,
ar_mape_gen,
ar_mape_min,
ar_mape_ind,
ge_mape_gen,
ge_mape_min,
ge_mape_ind,
list_tdiff,
list_t_pop,
list_t_pop_c,
list_t_pop_r,
list_mutacao,
max_comb,
res,
teste_mape
)
print('Parada por maximo de interações: ', ep+1 )
print('Menor Mape ' , min(arca_mape) )
print('Código ' , ar_mape_gen )
print('Indice Mutação Final: ' , indice_mut )
atualiza_arca(bool_salva_arca)
atualiza_arca(False)
200
"""# roda
# Comparativo Validação
"""
list_mape.append(np.array(list_mape).mean())
barras = [*Ycolumns, 'Média']
plt_barras(barras,list_mape)
Ycolumns
y_pred_list = []
mape_list = []
X,y,input_scaler,output_scaler,X_train,y_train,X_test,y_test,y_real,shape_i
n, shape_out = TrainTestData_old()
y_pred_list = np.array(y_pred_list).reshape(5,12)
plt_perfis_de_consumo2(y_pred_list.T)
"""#Fim"""
plt.show()
;