Prevendo o número de casos de COVID-19 em Uberaba usando Python

Leandro Cruvinel
7 min readJun 22, 2020

--

Thanks to Tai’s Captures for sharing their work on Unsplash.

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

Thanks to Adli Wahid for sharing their work on Unsplash.

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…

Thanks to Tom Pumford for sharing their work on Unsplash.

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. (•◡•) /

--

--

Leandro Cruvinel
Leandro Cruvinel

Written by Leandro Cruvinel

Math Professor | Data Scientist | Web developer

Responses (1)