Prevendo o número de casos de COVID-19 em Uberaba usando Python
Uberaba é uma das principais cidades do Triângulo Mineiro. Situa-se a 100 km de Uberlândia e é conhecida por ser a capital mundial do Zebu. A prefeitura de Uberaba fornece em seu site dados atualizados sobre número de casos e número de mortos associados a COVID-19 diariamente. Neste post criaremos um modelo para estimar o número total de casos em Uberaba nos próximos dias.
Existem várias formas de gerar modelos preditivos para estimar o número total de casos de COVID-19. Um dos mais simples é o ajuste de curvas paramétricas. Felizmente, a biblioteca scipy em Python oferece um método pronto para ser utilizado, bastando para isso termos em mãos os dados e a curva a ser ajustada.
Sumário
A seguir o passo a passo deste tutorial:
- Aquisição de dados
- Preparação do ambiente
- Preparação dos dados
- Exploração dos dados
- Modelagem
- Validação (ou quase)
- Prevendo os próximos dias
- Bônus: curva gaussiana
- Bônus: curva sigmoid
Aquisição de dados
Lembrando que o acesso ao site foi feito no dia 22/06/2020. Nem sempre sites permanecem no ar por longos períodos de tempo! Mas, se tiver no ar, é esse aqui: https://coviduberaba.github.io/
Ao entrar no site, encontraremos a imagem acima, ao clicar nela seremos direcionados para o Google Studio. Daí é só procurar o ícone abaixo:
Após encontrar, clique no mesmo e escolha a opção Download CSV. Após fazer o download, renomearemos o arquivo para data.csv por simplicidade.
Bom, qualquer coisa este mesmo arquivo está disponível para download no meu Github. Bem como todo o código, assim será possível copiar os scripts de maneira fácil por lá.
Preparação do ambiente
Para este projeto utilizamos o Jupyter Notebook. Essa ferramenta já vem no pacote de instalações do Anaconda. Utilizamos Python 3.7 e as bibliotecas matplotlib, numpy, pandas e scipy. Todas, juntamente com suas versões estão no arquivo requirements.txt no repositório do projeto.
Tudo instalado e já no Jupyter Notebook, importaremos as bibliotecas necessárias para o projeto!
Preparação dos dados
Utilizamos pandas para carregar os dados. Primeiro daremos uma boa olhada no que temos:
Ok, precisamos passar a coluna Data para o índice. Também eliminaremos todas as colunas, com exceção da Total Confirmados que é a de nosso interesse. Por fim, pra simplificar o código, renomearemos esta coluna para total.
Olhando as 5 primeiras linhas temos:
Dados preparados! Hora de explorar!
Exploração dos dados
Este tutorial é voltado para iniciantes, sendo assim, não faremos uma exploração com gráficos ou com estatísticas elaboradas. A ideia é passar por todo o processo para entendermos o passo a passo de um projeto de ciência de dados e obter resultados imediatos de forma simples. Sendo assim, a única coisa que faremos na exploração de dados é um gráfico de dispersão. Vejamos o código:
E temos então o gráfico:
Fica evidente a tal famosa curva que temos que achatar! Contudo, nossa intenção é estimar o número total de casos para os próximos dias. Para isso temos que escolher a função matemática paramétrica que siga o comportamento da curva acima e, utilizando os dados, estimar os parâmetros dessa função.
Hum… Apesar da curva parecer uma exponencial, com o tempo ela tente a diminuir a taxa de crescimento, uma vez que a população é finita. Mas, por hora, utilizaremos exponencial mesmo. Ao final do tutorial ajustaremos curvas gaussiana e sigmoid para fins de comparação.
Os passos então são:
- Criar a função com seus respectivos parâmetros
- Otimizar os parâmetros usando scipy
- Fazer um gráfico (porque é legal)
Olhando esse código ficamos…
Mas não devemos nos preocupar. Se ajustarmos qualquer conjunto de dados como ajustamos o nosso, nem precisaremos entender o código, só copiar e colar mesmo!!! (Por favor, sou professor, finjam que eu não disse isso. Finjam que disse que vocês têm que entender tudo, até as vírgulas.)
E esse código feio gera o gráfico lindo a seguir:
O mais importante é observar os valores dos parâmetros a, b e c. Precisaremos deles mais adiante.
Validação (ou quase)
Quanto à validação: técnicas gráficas e validação cruzada são fundamentais, mas, também, existem os testes estatísticos de aderência à curva ajustada, os famosos goodness-of-fit tests. Existem vários: Chi-square, Anderson-Darling, Cramer von Mises, Kolmogorov-Smirnov.
Neste post utilizamos todos os valores diários para gerar o modelo. Contudo, para uma validação eficaz, seria necessário guardar alguns num conjunto chamado conjunto de teste. A partir desse conjunto podemos realizar testes e “medir” o quão nosso modelo é “preciso” (As palavras em aspas têm significados mais profundos.) Existem diversas métricas para realizar esta etapa do projeto na biblioteca scikit-learn. Consideraremos apenas o gráfico como uma validação (Isso não é certo, mas enfim, tenho que acabar o post logo, porque se ficar grande ninguém lê até o final.) Em futuros tutoriais podemos trabalhar melhor essa parte.
Prevendo os próximos dias
Queremos saber o número total de casos amanhã e depois de amanhã! Já te falo que não vai dar certo se você tentar estimar o número de casos no próximo natal!
Como nosso modelo usa o número de dias, é preciso de uma função auxiliar pra transformar data em número de dias. Também precisamos da biblioteca datetime pra gerar as datas nas quais pretendemos estimar o número total de casos.
Observe que a função exp_model é análoga à função exp_func sendo que a primeira usa parâmetros fixos, que estimamos através da segunda!
Os números pareceram bem elevados, isso não quer dizer que será assim. O que fizemos foi ajustar os dados à uma curva exponencial. Se os dados seguirem a tendência dessa curva, ok, as estimativas representarão a realidade. Senão, é só mais um modelo dentre tantos.
Para tentar explicar melhor o parágrafo anterior, faremos a mesma estimativa usando outras duas curvas.
Bônus: curva gaussiana
Só pra recordar os passos:
- Criar a função
- Ajustar os parâmetros
- Usar o código feio pra ver o gráfico bonito
- Olhar se o gráfico está ok
- Estimar o número total de casos dos dois próximos dias
Os passos 1, 2 e 3 estão todos no código a seguir:
O código acima nem é tão feio quando nos acostumamos. Agora vejamos o gráfico lindo:
Bem, nosso modelo está bem encaixado à curva, suporemos que os dados seguem esse modelo. Agora podemos prever os próximos dias:
Os resultados foram um pouco menores, mas a diferença não foi tão grande. Use máscara!
Bônus: curva sigmoid
Já sabemos que temos que criar a função, ajustar os parâmetros e usar o código feio pra ver o gráfico bonito. Sendo assim:
Observe que dessa vez estimamos 4 parâmetros. Vejamos o gráfico:
Muito bem ajustado àcurva. Hora de prever o número total de casos!
Números bem menores.
Use máscara, não custa nada e não sabemos qual modelo está representando a verdade!
Considerações finais
Neste post usamos ajuste de curvas através da biblioteca scipy para estimar o número total de casos de COVID-19 nos dois próximo dias em Uberaba.
Agora que entendemos como funciona, podemos dar continuidade aos estudos com os seguintes passos:
- Usar conjuntos de treino e teste para validação dos modelos
- Usar métricas para medir a acurácia do modelo
- Testar novos modelos
Espero que tenham gostado! Não se esqueçam de deixar um comentário dizendo quais os próximos posts gostariam de ver por aqui!
Agradeço ao Matheus pelas dicas e correções.
Até a próxima. (•◡•) /