Você tem interesse em data science e está sensibilizado com a situação da COVID-19 no Brasil? Neste post, irei explorar o conceito de data acquisition e demonstrar como utilizar uma técnica simples de web scraping para obter dados oficiais sobre o avanço da doença. Vale dizer que, com alguma adaptação no código, a estratégia aqui empregada pode ser facilmente estendida a dados de outros países ou ainda a outras aplicações. Então ponha sua máscara, lave suas mãos e inicie a leitura agora mesmo!

Click here for an English version of this post.


Devo iniciar este texto, antes de tudo, oferecendo os mais sinceros sentimentos a todas as vítimas da COVID-19. De fato, é em memória destes que devemos buscar motivação para o desenvolvimento da ciência, em todas as suas áreas e expressões, sem esquecermos de que se ela existe é porque há uma humanidade que a sustenta. Em relação à ciência de dados, é através dela que podemos minimizar fake news e contribuir, de alguma forma, com uma sociedade mais informada, sensata e ponderada.

Iniciei este projeto de exploração de dados ao perceber, há algumas semanas atrás, que havia pouca informação estratificada sobre o número de casos da COVID-19 no Brasil em bases oficiais, tais como a da Organização Mundial da Saúde (WHO – World Health Organization) ou do painel mantido pela Universidade John Hopkins. Como estratificado, aliás, entende-se o conjunto de dados que pode ser observado em diferentes camadas. Ou seja, para um país de dimensões continentais, como o Brasil, saber o número total de casos no país é apenas informativo. Para que tal informação seja funcional, ela deve ser estratificada por regiões, estados, ou cidades.

De modo a proporcionar tanto uma visão geral do problema quanto direcionar o desenvolvimento da análise, estabeleci abaixo alguns objetivos para este estudo dos quais espero que o leitor também se aproprie:

  • Adquirir uma visão geral do processo de KDD e compreender onde a aquisição de dados está inserida.
  • Explorar técnicas de aquisição de dados de modo que possam ser facilmente empregadas em problemas e casos similares.
  • Obter, a partir de bases de dados oficiais, o número de casos e óbitos por COVID-19 no Brasil, estratificado por estado.

Nas seções a seguir, exploraremos cada um desses itens buscando construir os conceitos necessários e implementá-los de maneira prática em um ambiente de desenvolvimento em Python. Prontos?


KDD – Descobrindo conhecimento em bases de dados

A descoberta de conhecimento em bases de dados, mais conhecida por sua sigla KDD, do inglês Knowledge Discovery in Databases, é o processo pelo qual se busca padrões compreensíveis, válidos, e relevantes a partir de bases de dados. É um processo interativo e iterativo, que compreende muitas das técnicas e processos conhecidos atualmente como ciências de dados.

Antes de explorarmos as principais etapas do processo de KDD, porém, vale diferenciarmos três termos-chaves: dados, informações e conhecimento. Cada etapa do processo de KDD, aliás, ocupa-se de processar cada um desses termos, ilustrados no diagrama da Fig. 1 a partir da problemática em que estamos trabalhando.

Figura 1. Dos dados ao conhecimento: o processamento da informação no KDD.

Em resumo, dados são todas as cadeias de símbolos, estruturadas ou não, relacionadas a algum fenômeno ou evento. Um dado, por si, não traz significado algum. Veja: o número 4,08 milhões é apenas um cardinal inteiro. Ele se torna assustador somente após atribuirmos a ele o significado de que esta é a quantidade de casos confirmados da COVID-19. Ou seja, somente ao atribuirmos um significado a um dado é que passamos a ter uma informação.

É a partir da manipulação da informação que adquirimos conhecimento. Este, por sua vez, está íntima e etimologicamente ligado ao que chamamos de “processos cognitivos” — a percepção, a contextualização e o aprendizado — e, por conseguinte, à inteligência.

Uma vez compreendidos estes três conceitos, podemos agora avançar para as três etapas fundamentais do processo de KDD. Estas nada mais são do que conjuntos de tarefas respectivamente dedicadas à obtenção e exploração dos dados, informações e conhecimento, conforme ilustrado na Fig. 2, abaixo:

Figura 2. O processo de KDD e suas etapas de (i) aquisição dos dados, (ii) processamento das informações e (iii) extração do conhecimento.

O processo de KDD, portanto, é constituído de etapas e cada qual, de tarefas. As tarefas de data mining, por exemplo, fazem parte da etapa de processamento da informação, enquanto que as tarefas relacionadas à visualização de dados, analytics, e tomada de decisão constituem a última etapa, pela qual se extrai o conhecimento.

Neste artigo, vamos nos deter somente à tarefa de aquisição de dados (data acquisition), fundamental a todo e qualquer processo de KDD. De modo geral, não existe um método pré-definido e generalista para a obtenção dos dados. Em um projeto de médio e longo prazos, normalmente desenvolve-se um modelo de dados e uma arquitetura robusta para a sua coleta e armazenamento. Já em projetos de curto prazo, ou então em análises como esta, utilizam-se as fontes imediatamente disponíveis e acessíveis que mais estejam relacionadas ao problema.

Tendo estes conceitos fundamentais em mente, estamos prontos para seguir em direção ao nosso propósito: a aquisição de dados oficiais sobre o número de casos da COVID-19.


Definindo uma estratégia de aquisição de dados

Como vimos, uma estratégia de aquisição de dados só fará sentido se for construída a partir da perspectiva de um processo completo de KDD. Isto é, antes de sairmos coletando dados por aí, precisamos ter bem definido qual é o propósito disto tudo. Ou ainda, qual é o problema que estamos tentando resolver ou elucidar?

O modelo de referência CRISP-DM, representado na Fig.3, pode ser utilizado como uma bússula ao percorrermos um processo de KDD. Você se recorda que anteriormente definimos o KDD como um processo interativo e iterativo?

Pois bem, a interação pode ser definida como a ação mútua ou compartilhada entre dois ou mais agentes. Neste caso, a interação pode se referir tanto entre as pessoas detentoras de dados e informações, ou entre as etapas. As setas curtas, em ambos os sentidos entre os primeiros passos da Fig. 3, representam justamente a interação necessária no processo. Ouso dizer que tal interação é o maior desafio dos recém-chegados ao mundo do KDD ou data science: há uma ilusão inicial de que os passos devem ser seguidos em um fluxo contínuo, o que logo decorre em uma sensação de se estar fazendo algo errado. Muito pelo contrário, é a compreensão do negócio que possibilita a compreensão dos dados, que gera novos insights sobre o negócio e assim por diante.

A iteração, por sua vez, está associada à repetição do mesmo processo. As setas maiores, na Fig.3, formam um círculo que simboliza esta repetição. Inicia-se no primeiro passo e retorna-se, após o desenvolvimento, novamente a ele. Enquanto estiver ativo, um projeto de data science ou KDD nunca ficará estagnado.

Figura 3. Fases do processo de KDD de acordo com o modelo de referência CRISP-DM.(Adaptado de Wikimedia Commons.)

As caixas destacadas, na Fig. 3, representam os passos relacionados à aquisição de dados, sendo nelas que iremos nos deter a partir daqui, embora de modo um tanto simplificado.

De acordo com o CRISP-DM, o primeiro passo — a compreensão do negócio — é fundamental para o sucesso de todo o projeto e compreende (i) a definição dos objetivos do negócio; (ii) a avaliação da situação atual, incluindo inventários e análises de risco, bem como quais dados e informações já estão disponíveis; (iii) a determinação dos objetivos em se aplicar data mining, assim como a definição de quais serão os critérios de sucesso; e (iv) a elaboração de um plano de projeto.

O segundo passo — o entendimento dos dados — compreende (i) a coleta inicial dos dados e (ii) sua descrição detalhada; (iii) a exploração inicial dos dados; e (iv) uma avaliação da qualidade desses dados. Lembre-se de que estes dois passos iniciais ocorrem de maneira interativa e, idealmente, envolvendo especialistas de domínio e de negócio.

O terceiro passo inicia-se com a validação do plano de projeto pelo cliente ou pelo sponsor e caracteriza-se pela preparação dos dados. Em linhas gerais, os esforços necessários nesta fase tornam-se maiores e, portanto, suas alterações devem ser mais brandas. As principais tarefas desta etapa compreendem a seleção e limpeza dos dados, a construção e a adequação do formato, e a integração de dados (merging). Todas essas tarefas são normalmente referidas como pré-processamento dos dados.

Sua estratégia de aquisição de dados começará a ser definida tão logo você tenha as primeiras interações entre a compreensão do negócio (ou do problema) e o entendimento dos dados disponíveis. Para tanto, considero essencialmente dois cenários possíveis:

  1. Há controle sobre a origem dos dados: você pode, de algum modo, gerenciar e controlar as fontes geradoras dos dados (sensores, medidores, pessoas, bancos de dados, etc.). Tome, como exemplo, a atividade de um enfermeiro-chefe: ele pode supervisionar, auditar, estabelecer protocolos e realizar o registro de todos os dados de pacientes em sua enfermaria. É importante salientar que o controle é sobre a origem ou registro dos dados, e não sobre o evento ao qual os dados estão relacionados.
    Este é geralmente o cenário de projetos de grande complexidade ou duração, onde se estabelece um modelo de dados e se estabelecem meios para garantir sua consistência e integridade.
  2. Não há controle sobre a origem dos dados: esta é a situação mais comum em projetos de curta duração ou de interesse ocasional, assim como projetos, análises ou estudos perenes que utilizem ou demandem dados de outras fontes que não as próprias. Seja qual for a iniciativa, a estratégia de aquisição de dados deve ser ainda mais fortalecida, dado que qualquer alteração — que está além do seu controle — pode aumentar os custos de sua análise ou mesmo inviabilizar o projeto.
    Este cenário é ilustrado pelo nosso próprio estudo: como obter o número estratificado de casos da COVID-19, no Brasil, se não temos controle sobre a produção e divulgação destes dados?

Espere encontrar o cenário (1) ao atuar em ambientes corporativos e instituições, ou ao liderar pesquisas longitudinais ou então processos de fabricação. De outro modo, é bem provável que você tenha de lidar com o cenário (2). Neste caso, sua estratégia poderá compor-se de subscrições (assinatura de serviços), acordos de cessão de dados, ou ainda de técnicas que busquem e compilem tais dados a partir da Internet, desde que devidamente licenciados. A atividade de web scraping é uma destas técnicas, como veremos a seguir.


Aquisição de dados por web scraping: obtendo os dados via painel oficial do Ministério da Saúde

Uma vez estabelecido o objetivo — o número estratificado de casos da COVID-19 no Brasil — minha primeira ação foi buscar quais seriam as possíveis fontes. Consultei o portal do Ministério da Saúde em meados de Abril/2020. Na ocasião, não havia encontrado informações consolidadas e de fácil acesso, de modo que aumentei a granularidade das possíveis fontes: secretarias estaduais e municipais de saúde. O desafio, neste caso, foi a heterogeneidade no modo com que os dados eram apresentados (quando eram). Ao consultar uma servidora pública da área da saúde, fui informado de que os dados eram consolidados nos boletins, e que demandas específicas deveriam ser solicitadas institucionalmente. Minha primeira estratégia, então, foi elaborar um meio de automaticamente coletar tais boletins (em formato PDF) e começar a extrair deles os dados desejados — parte do resultado está disponível no repositório GitHub deste projeto.

No início de Maio/2020, porém, tive uma desagradável surpresa: as tabelas que até então eu utilizara para extrair os dados de meu interesse (para quem tiver curiosidade, a biblioteca PDFplumber é uma excelente ferramenta) foram substituídas por figuras, nos novos boletins, o que inviabilizou o meu método de extração.

Fiz questão de discorrer em detalhes os parágrafos acima por uma simples razão: demonstrar, mais uma vez, o processo interativo inerente à etapa de aquisição de dados, no KDD. Além disso, quis evidenciar os riscos e incertezas ao assumirmos um projeto onde não temos controle sobre a origem dos dados. Nessas situações, é sempre bom contar com alternativas, estabelecer parcerias ou convênios, e buscar construir sua própria base de dados.

Ao passo em que eu buscava uma nova estratégia, o Ministério da Saúde passou a disponibilizar os dados já compilados em um único arquivo CSV — dias depois alterando o formato para XLSX e variando o nome do arquivo a cada dia. Nos parágrafos a seguir, detalharei como adequei meu processo e meu código para esta nova situação.

A propósito, a obtenção automática de dados e informações a partir de páginas e conteúdos disponibilizados na Internet é denominada web scraping. Tal técnica pode ser implementada de maneira bastante simples, utilizando bibliotecas disponíveis em Python, conforme esquematizado na Fig. 4.

Figura 4. Etapas de um processo simplificado de web scraping utilizando a ferramenta de inspeção do Google Chrome e a linguagem Python.

Chegamos finalmente à parte prática — e talvez a mais esperada — deste texto. Seguindo as etapas definidas na Fig. 4, começamos por (1) visitar o Painel Coronavírus Brasil e (2) identificar que o nosso interesse está nos dados disponibilizados ao clicarmos no botão “Arquivo CSV”, no canto superior direito da página. Ao ativarmos a ferramenta de inspeção de páginas do Google Chrome (3), localizamos o código correspondente ao item na página HTML, conforme mostrado na Fig. 5. Lembrando que a ferramenta de inspeção é ativada pelo menu Inspecionar, ao clicarmos com o botão direito sobre algum elemento da página, ou pelo atalho ctrl+shift+I.

Figura 5. Portal Coronavírus Brasil visto através da ferramenta de inspeção do Google Chrome.

O passo seguinte (4) é acessar estes dados a partir de linhas de código em Python, o que pode ser feito através de cadernos do Jupyter, scripts, ou através de uma IDE. Em qualquer dos casos, a ideia é emular o acesso ao portal desejado e a interação com a página web, utilizando para isso a biblioteca Selenium.

No código abaixo, inicio criando um ambiente virtual para em seguida acessar o site de interesse com o emulador do Google Chrome:

# Declarações iniciais
from pyvirtualdisplay import Display
from selenium import webdriver

# Definição de parâmetros
url = 'https://covid.saude.gov.br'
## A linha abaixo pode ser suprimida em alguns ambientes:
chromeDriverPath = '~/anaconda3/envs/analytics3/'

# Inicializa o display (tela virtual):
display = Display(visible=0, size=(800,600))
display.start()

# Abre o emulador do Chrome para o site desejado:
driver = webdriver.Chrome()

# Lê o conteúdo da página, armazenando-o em UTF-8:
driver.get(url)
page = driver.page_source.encode('utf-8')

Uma vez realizada a leitura da página, seguimos para o passo (5) da Fig. 4, onde iteramos o processo até garantir a obtenção dos dados na forma desejada. Para tanto, podemos iniciar verificando o tamanho da página carregada (se for nulo, significa que algo deu errado) e suas primeiras linhas:

# Qual é o tamanho da página carregada?
print(len(page))

# Qual é o tipo de dados?
print(type(page))

# Qual é o conteúdo das primeiras posições do fluxo de bytes?
print(page[:2000])

Na maioria das vezes, o passo seguinte seria explorar o conteúdo HTML através de ferramentas conhecidas como parsers — a biblioteca BeautifulSoup cumpre muito bem esta função em Python. No nosso caso, considerando que os dados de interesse não estão na página web, mas sim resultam de uma ação nesta página, iremos seguir utilizando apenas os métodos do Selenium para emular o clique sobre o botão, automaticamente fazendo o download do arquivo desejado para a pasta padrão do sistema:

## Caminho obtido a partir da inspeção no Chrome:
xpathElement = '/html/body/app-root/ion-app/ion-router-outlet/app-home/ion-content/div[1]/div[2]/ion-button'

## Elemento correspondente ao botão "Arquivo CSV":
dataDownloader = driver.find_element_by_xpath(xpathElement)

## Download do arquivo para a pasta padrão do sistema:
dataDownloader.click()

O passo seguinte é verificarmos se o download do arquivo foi realizado corretamente. Dado que o nome do arquivo não é padronizado, a listagem é feita através da biblioteca glob:

import os
import glob

## Obtendo o nome do arquivo XLSX mais recente:
list_of_files = glob.glob('/home/tbnsilveira/Downloads/*.xlsx') 
latest_file = max(list_of_files, key=os.path.getctime)
print(latest_file)

A partir deste ponto, podemos considerar finalizada a tarefa de web scraping, ao mesmo tempo em que adentramos na fase de preparação dos dados (se necessário, reveja a Fig. 3).

Vamos considerar que estamos interessados na quantidade de casos por estado, em relação à sua população, assim como nas taxas de letalidade (número de óbitos em relação ao número de casos) e de mortalidade (número de óbitos em relação à população). As linhas de código abaixo realizam o pré-processamento dos dados obtidos de modo a oferecer as informações desejadas.

## Leitura dos dados
covidData = pd.read_excel(latest_file)
covidData.head(3)

## Obtendo a última data registrada:
lastDay = covidData.data.max()

## Selecionando o dataframe apenas com os dados do último dia
## E cujos dados sejam consolidados por estado
covidLastDay = covidData[(covidData.data == lastDay) &
                         (covidData.estado.isna() == False) & 
                         (covidData.municipio.isna() == True) &
                         (covidData.populacaoTCU2019.isna() == False)]

## Selecionando apenas as colunas de interesse:
covidLastDay = covidLastDay[['regiao','estado','data','populacaoTCU2019','casosAcumulado','obitosAcumulado']]

A etapa de pré-processamento é concluída ao gerarmos algumas features adicionais, a partir dos dados pré-existentes:

## Cópia do dataframe antes de manipulá-lo:
normalCovid = covidLastDay.copy()

## Taxa de contaminação (% de casos pela população de cada estado)
normalCovid['contamRate'] = (normalCovid['casosAcumulado'] / normalCovid['populacaoTCU2019']) * 100
## Taxa de letalidade (% de óbtiso pelo núm. casos)
normalCovid['lethality_pct'] = (normalCovid['obitosAcumulado'] / normalCovid['casosAcumulado']) * 100
## Taxa de mortalidade (% de óbitos pela população de cada estado)
normalCovid['deathRate'] = (normalCovid['obitosAcumulado'] / normalCovid['populacaoTCU2019']) * 100

A partir deste ponto, podemos fazer buscas na base de dados pré-processada:

normalCovid.query("obitosAcumulado > 1000")

Aqui encerramos a etapa de aquisição de dados. Se seguirmos a metodologia CRISP-DM, os passos seguintes poderiam ser tanto a construção de modelos, análises ou visualizações. Para ilustrar uma possível conclusão deste processo de KDD, a Fig. 6 apresenta um gráfico do tipo Four-Quadrant correlacionando o percentual de casos versus a taxa de letalidade nos diferentes estados do Brasil (o código para gerá-lo está disponível no GitHub).

Figura 6. Relação entre número de casos da COVID-19 e a letalidade, por estados do Brasil, conforme dados divulgados pelo Ministério da Saúde no dia 22/05/2020.

O gráfico acima é o resultado de todo o processo percorrido: os dados foram obtidos via web scraping, as informações foram geradas a partir da manipulação desses dados, e o conhecimento foi adquirido ao se estruturar a informação. O Amazonas (AM) é o estado brasileiro com o maior número de infecções por habitante, assim como a maior taxa de letalidade. São Paulo (SP) é o estado com o maior número acumulado de óbitos, porém com um número de infecções relativamente baixo considerando toda a sua população.


Considerações finais

Neste artigo busquei oferecer uma visão geral do processo de KDD e de como a aquisição de dados pode ser implementada a partir da técnica de web scraping, principalmente em se tratando de pequenos projetos ou análises.

Talvez você tenha se perguntado, ao longo da leitura, se não seria muito mais fácil apenas visitar o portal e simplesmente fazer o download dos dados lá disponíveis. Sim, seria! Contudo, o que se espera em um projeto de data science é que a obtenção dos dados seja a mais automática possível, dando espaço para que se avance com análises preditivas cujos modelos demandem atualização diária ou constante dos dados. Além disso, compreender temas complexos e ganhar confiança sobre a nossa própria técnica torna-se muito mais efetivo — e quiçá divertido — com problemas relativamente mais simples.

Por fim, devo lembrá-lo a sempre agir com ética na coleta e na manipulação de dados. Automatizar a coleta de dados de domínio público, sem ônus à sua administração, caracteriza-se como uma atividade completamente legal. Entretanto, se estiver em dúvida sobre quando é permitido ou não o uso de algoritmos deste tipo, não hesite em consultar especialistas ou mesmo os proprietários dos dados.


Se você acompanhou o artigo até aqui, gostaria muito de conhecer a sua opinião. Além da enquete abaixo, sinta-se à vontade para deixar um comentário ou escrever-me com dúvidas, críticas ou sugestões.