Marcus Nunes http://marcusnunes.me Sou cientista de dados e meu cachorro se chama Fisher Tue, 24 Apr 2018 18:22:36 +0000 en-US hourly 1 https://wordpress.org/?v=4.9.5 Controle de gastos públicos: como verificar quanto os deputados federais estão gastando http://marcusnunes.me/controle-de-gastos-publicos-como-verificar-quanto-os-deputados-federais-estao-gastando/ Mon, 02 Apr 2018 11:40:43 +0000 http://marcusnunes.me/?p=481 … ]]> Introdução

2018 é ano de eleição. Em teoria, alguns milhões de brasileiros que vão às urnas em 7 de outubro escolher seus candidatos para vários cargos. Infelizmente, os debates sobre as eleições no Brasil ficam concentrados na escolha dos nomes para os cargos do executivo. As pessoas tendem a se preocupar com o novo presidente, muitas vezes imaginando que vão eleger um salvador da pátria que vai, magicamente, resolver todos os problemas do país. O sebastianismo pode ter acabado em Portugal, mas continua firme e forte por aqui.

O problema é que depois das eleições vem a realidade e a realpolitik chega com força. O presidente não governa sozinho. Ele precisa negociar com os deputados e senadores. Portanto, escolher um bom deputado, alguém que não seja um dos 400 achacadores do congresso, é tão importante quanto escolher o presidente.

O site Ranking dos Políticos tenta organizar as informações disponíveis sobre os atuais deputados e senadores. Este site junta informações de diversas fontes, a fim de avaliar como está o cumprimento dos deveres dos nobres legisladores.

Outra organização interessada em avaliar o desempenho dos deputados e senadores é a Operação Serenata de Amor. Este pessoal pega as informações disponibilizadas pela Câmera e pelo Senado, formata elas de maneira acessível e distribui para quem quiser verificar. Inclusive, escreveram um módulo para python que simplifica demais esta tarefa.

O problema é que é um módulo para python. Nem todos os estatísticos do Brasil trabalham com o python. Em geral, a gente1 entende mais de R. Pensando nisso, utilizei a ferramenta criada pelo Serenata de Amor para baixar os dados de reembolso dos deputados. Em seguida, criei um pacote com os dados de reembolsos pedidos pelos deputados e pagos pelo governo, disponibilizando para quem quiser usar. A seguir vou mostrar como instalar e utilizar o pacote que criei, além de mostrar algumas análises que fiz.

Como Usar o Pacote

Meu pacote não está no cran. Hospedei ele no GitHub (me segue lá), uma rede social para programadores. Apesar de isto me dar um pouco mais de liberdade, acaba deixando a instalação do pacote menos direta para o usuário, pois é necessário realizar um passo a mais antes da instalação.

Para instalar meu pacote reembolsos, é necessário instalar primeiramente o pacote devtools através do comando

install.packages("devtools")

Com o devtools instalado, fica trivial instalar meu pacote:

library(devtools)
install_github("mnunes/reembolsos")

Ou seja, com três linhas de código2 é possível ter acesso a todos os pedidos de reembolsos feitos pelos deputados e senadores entre 2009 e 2017. São 9 anos de dados reais e livres, disponíveis para quem quiser analisar.

A instalação deve demorar um pouquinho, pois os deputados e senadores pediram vários reembolsos nos último 10 anos. No dia em que publiquei este post, haviam 3.099.310 pedidos únicos de reembolso (sim, três milhões). Portanto, há várias informações a serem baixadas. Seja paciente.

O que dá pra fazer com o Pacote

Excelente pergunta. Dá pra fazer tudo com este pacote. Quer dizer, tudo o que envolva analisar pedidos de reembolso dos deputados federais. Por exemplo, dá pra verificar quanto dinheiro foi reembolsado para os deputados brasileiros entre 2009 e 2017:

library(reembolsos)
theme_set(theme_bw())

camara %>%
  select(total_net_value, year) %>%
  group_by(year) %>%
  summarise(total=sum(total_net_value)) %>%
  print(n=Inf) %>%
  ggplot(., aes(x=year, y=total/1e6)) +
  geom_line() +
  labs(x="Ano", y="Reembolsos (em milhões de R$)") +
  scale_x_continuous(breaks = seq(2009, 2017, 1), minor_breaks = NULL) +
  scale_y_continuous(limits = c(0, 250))

# A tibble: 9 x 2
   year      total
        
1  2009 115404993.
2  2010 154391858.
3  2011 171927438.
4  2012 170508922.
5  2013 188930589.
6  2014 196061150.
7  2015 213804407.
8  2016 221070448.
9  2017 225362468.

Perceba que este resultado não faz discriminação nenhuma, nem leva em conta a inflação do período. Ele apenas mostra os reembolsos totais pagos a todos os deputados somados. Não é possível ver muita coisa, a não ser que estes gastos vem aumentando com o tempo. Entretanto, é possível fazer uma análise como esta por partido:

camara %>%
  select(party, total_net_value, year) %>%
  group_by(party, year) %>%
  summarise(total=sum(total_net_value)) %>%
  ggplot(., aes(x=year, y=total/1e6, colour=party)) +
  geom_line() +
  labs(x="Ano", y="Reembolsos (milhões de R$)", colour="Partido") +
  scale_x_continuous(breaks = seq(2009, 2017, 1), minor_breaks = NULL) +
  scale_y_continuous(limits = c(0, 35))

Embora consigamos ver algumas coisas interessantes, como uma grande diminuição no valor de reembolsos feitos aos deputados do PT após 2014 (o que não deveria ser uma surpresa, pois o partido elegeu menos deputados nas últimas eleições se comparado com o número de eleitos em 2010), esta visualização está muito poluída. Vamos nos restringir apenas aos 7 partidos com o maior valor total de reembolsos pagos:

maiores <- camara %>%
  select(party, total_net_value, year) %>%
  group_by(party) %>%
  summarise(total=sum(total_net_value)) %>%
  arrange(desc(total)) %>%
  head(n=7) %>%
  select(party) %>%
  unlist() %>%
  as.vector()

camara %>%
  select(party, total_net_value, year) %>%
  filter(party %in% maiores) %>%
  group_by(party, year) %>%
  summarise(total=sum(total_net_value)) %>%
  group_by(year) %>%
  print(n=Inf) %>%
  ggplot(., aes(x=year, y=total/1e6, colour=party)) +
  geom_line() +
  labs(x="Ano", y="Reembolsos por Partido (milhões de R$)", colour="Partido") +
  scale_x_continuous(breaks = seq(2009, 2017, 1), minor_breaks = NULL) +
  scale_y_continuous(limits = c(0, 35))

Pronto. A visualização melhorou um pouco. Temos PT e PMDB liderando os reembolsos, com valores totais na ordem de R$25 milhões em 2017, e um grupo de cinco outros partidos com valores de reembolso variando entre R$15 e R$20 milhões no mesmo ano.

Mas PMDB e PT possuem os maiores números de deputados. É natural que eles gastem mais em termos absolutos. Como será que é o gasto médio por reembolso se analisarmos apenas estes sete partidos?

camara %>%
  select(party, total_net_value, year) %>%
  filter(party %in% maiores) %>%
  group_by(party, year) %>%
  summarise(media=mean(total_net_value)) %>%
  group_by(year) %>%
  print(n=Inf) %>%
  ggplot(., aes(x=year, y=media, colour=party)) +
  geom_line() +
  labs(x="Ano", y="Reembolsos Médios por Partido (R$)", colour="Partido") +
  scale_x_continuous(breaks = seq(2009, 2017, 1), minor_breaks = NULL) +
  scale_y_continuous(limits = c(0, 800))

Hum… Os deputados do PR apresentaram valor médio de quase R$800 por reembolso pago. Aliás, dentro do grupo de sete partidos considerado, os deputados do PR são os que tem o reembolso médio mais alto desde 2009. Os deputados do PT foram os que pediram reembolsos médios de menor valor em 2017. Como eles são em número maior e apresentam mais pedidos, o valor total de todos os reembolsos acaba ficando mais alto do que os outros partidos.

Mas as análises que podem ser realizadas não ficam apenas em comparar partidos. É possível comparar deputados e os lugares onde eles gastaram o nosso dinheiro. Podemos ver, por exemplo, todas as vezes em que um deputado fez uma refeição em algum restaurante e gastou mais do que a média dos outros deputados. Um bom restaurante para fazermos isto é o McDonald’s, pois ele está presente no Brasil inteiro e muita gente tem ideia de quanto custa uma refeição neste local.

Veja como o pacote reembolsos permite que vejamos quais foram os gastos mais altos da história da câmara nesta lanchonete:

camara %>%
  select(year, supplier, congressperson_name, party, total_net_value) %>%
  filter(grepl("donald", supplier, ignore.case=TRUE)) %>%
  arrange(desc(total_net_value))

# A tibble: 643 x 5
    year supplier                           congressperson_name party total_net_value
                                                            
 1  2009 MC DONALDS                         CELSO RUSSOMANNO    PRB              84.0
 2  2014 MC DONALDS                         FRANCISCO FLORIANO  DEM              80.0
 3  2014 MC DONALDS                         EURICO JÚNIOR       PV               73.0
 4  2015 MC DONALDS                         CELSO RUSSOMANNO    PRB              71.5
 5  2009 MC DONALD'S -LMO COMERCIO DE ALIM… PAULO ROBERTO PERE… PTB              67.2
 6  2015 MC DONALDS                         CÉSAR MESSIAS       PSB              64.5
 7  2013 MCDONALDS COMÉRCIO DE ALIMENTOS L… MAGDA MOFATTO       PR               64.0
 8  2016 MC DONALDS                         CÉSAR MESSIAS       PSB              60.0
 9  2010 MC DONALDS                         JOSÉ MENTOR         PT               57.0
10  2015 MC DONALD'S COM DE ALIM LTDA       POMPEO DE MATTOS    PDT              57.0
# ... with 633 more rows

Dentre os 643 gastos feitos pelos deputados no McDonald’s, alguns se destacam. Note que em 2009, Celso Russomanno, deputado federal pelo PRB, gastou R$84,00 em apenas uma ida ao McDonald’s. Se hoje, em 2018, depois de nove anos de inflação acumulada, um Big Mac com refrigerante e batata frita média custa menos de R$25,00, podemos dizer que R$84,00 foi um gasto bastante elevado para o padrão desta lanchonte.

O interessante é que podemos comparar o gasto do deputado com os outros 642 pedidos de reembolso realizados neste mesmo restaurante, calculando a média e o desvio padrão dos reembolsos. E aí descobrimos o seguinte:


camara %>%
  select(year, supplier, congressperson_name, party, total_net_value) %>%
  filter(grepl("donald", supplier, ignore.case=TRUE)) %>%
  summarise(Media=mean(total_net_value), SD=sd(total_net_value))

# A tibble: 1 x 2
  Media    SD
   
1  23.1  12.3

A média de pedidos de reembolso no McDonald’s, entre 2009 e 2017, sem considerar a inflação, foi de R$23,10, com desvio padrão de R$12,30. Ou seja, este gasto específico de R$84,00 está 4,94 desvios padrão acima da média dos gastos dos outros deputados federais neste restaurante. Pra quem é leigo no assunto, isto significa que é um gasto muito alto. Talvez seja interessante investigar os detalhes desta compra pra ver que não houve algum cadastro errado no valor informado e reembolsado para o deputado. Deputado este que não foi o único a gastar muito no McDonald’s:


camara %>%
  select(year, supplier, congressperson_name, party, total_net_value) %>%
  filter(grepl("donald", supplier, ignore.case=TRUE)) %>%
  arrange(desc(total_net_value)) %>%
  mutate(z=scale(total_net_value))

# A tibble: 643 x 6
    year supplier                      congressperson_na… party total_net_value     z
                                                       
 1  2009 MC DONALDS                    CELSO RUSSOMANNO   PRB              84.0  4.94
 2  2014 MC DONALDS                    FRANCISCO FLORIANO DEM              80.0  4.61
 3  2014 MC DONALDS                    EURICO JÚNIOR      PV               73.0  4.05
 4  2015 MC DONALDS                    CELSO RUSSOMANNO   PRB              71.5  3.92
 5  2009 MC DONALD'S -LMO COMERCIO DE… PAULO ROBERTO PER… PTB              67.2  3.58
 6  2015 MC DONALDS                    CÉSAR MESSIAS      PSB              64.5  3.36
 7  2013 MCDONALDS COMÉRCIO DE ALIMEN… MAGDA MOFATTO      PR               64.0  3.32
 8  2016 MC DONALDS                    CÉSAR MESSIAS      PSB              60.0  2.99
 9  2010 MC DONALDS                    JOSÉ MENTOR        PT               57.0  2.75
10  2015 MC DONALD'S COM DE ALIM LTDA  POMPEO DE MATTOS   PDT              57.0  2.75
# ... with 633 more rows

Perceba que 7 deputados gastaram no McDonald’s valores pelo menos 3 desvios padrão acima da média dos gastos dos outros deputados. Aparentemente, tinha gente muito faminta indo comer neste local.

Veja bem: pedir reembolso por gastos com alimentação do deputado não é algo ilegal. Não há problema algum nisso. O site da Câmara esclarece isto muito bem. Entretanto, o deputado não pode usar o dinheiro do contribuinte para pagar refeições para alguém que não seja ele próprio. Assim sendo, talvez seja interessante verificar detalhadamente o que houve neste episódio. O Serenata de Amor já faz isto de forma automatizada. Podemos ver, por exemplo, que o local do Paulo, em uma lanchonete localizada no Itaim Bibi.i feito em São Paulo, em uma lanchonete localizada no Itaim Bibi.

Conclusão

As aplicações deste pacote são muitas. É possível desde escrever artigos analisando os gastos dos deputados, até construir ferramentas interativas que permitam à sociedade fazer as suas próprias análises. Ou, quem sabe, criar algoritmos capazes de identificar gastos muito discrepantes que os deputados podem ter realizado, como a compra de R$84,00 que o Celso Russomano fez no McDonald’s.

Entretanto, o pacote ainda não está pronto. É necessário completar e traduzir o help para o português, bem como adicionar os pedidos de reembolso do Senado Federal. Estes são trabalhos futuros, a serem realizados brevemente (ou não).

Quem estiver interessado em brincar com estes dados só precisa entrar no GitHub do pacote reembolsos e seguir as instruções para instalá-lo em seu computador.


1 Eu não sou estatístico, na verdade. Como meu curso de graduação foi um Bacharelado em Matemática Aplicada e tenho apenas um Doutorado em Estatística, a lei não permite que eu seja considerado um estatístico. Por isso me identifico como Cientista de Dados.

2 Ou apenas uma, se o usuário já tiver o devtools instalado e resolver executar o comando devtools::install_github("mnunes/reembolsos") para instalar este pacote

]]>
Utilizando Estatística para Decidir qual Cerveja Beber – Parte 2 http://marcusnunes.me/utilizando-estatistica-para-decidir-qual-cerveja-beber-parte-2/ Tue, 27 Feb 2018 11:30:51 +0000 http://marcusnunes.me/?p=442 … ]]> Sou maior de idade, pago meus impostos e contribuo para o PIB. Portanto, nada me impede de ocasionalmente beber uma ou outra cerveja em meus momentos de lazer. Embora eu tenha as minhas preferências pessoais neste assunto, estive pensando qual seria a opinião geral do brasileiro a respeito das cervejas disponíveis no mercado. De acordo com o G1, cada brasileiro consumiu, em média, 60,7 litros de suco de cevada em 2017, o que serve como indicativo do quanto o povo daqui curte uma ampola (ou talvez mais) deste diurético.

Pensando em analisar quantitativamente a opinião do brasileiro sobre as cervejas que consome, eu mostrei em meu post anterior como fiz para obter informações a respeito de

  • Avaliação Geral
  • Aroma
  • Aparência
  • Sabor
  • Sensação
  • Conjunto

das 1000 cervejas com mais avaliações no Brejas.

As Melhores Cervejas e Estilos

Podemos começar a análise com as 10 cervejas com avaliação geral mais alta:

# cervejas melhor avaliadas

dados %>% 
  select(Nome, Geral, Votos) %>%
  arrange(desc(Geral))

# A tibble: 1,000 x 3
   Nome                                     Geral Votos
                                        
 1 Westvleteren Abt 12                       4.70   106  
 2 Westvleteren Extra 8                      4.60    47
 3 Ola Dubh Special Reserve 40               4.60    33
 4 Founders KBS (Kentucky Breakfast Stout)   4.60    37
 5 Trappistes Rochefort 10                   4.50   213  
 6 Biertruppe Vintage Nº 1                   4.50    29
 7 Thomas Hardy's Ale                        4.50    41
 8 Gouden Carolus Cuvée van de Keizer Blauw  4.40    77
 9 St. Bernardus Abt 12                      4.40   140  
10 Founders Backwoods Bastard                4.40    32
# ... with 990 more rows

Ao que tudo indica, a cerveja Westvleteren Abt 12 é a melhor cerveja avaliada pelos usuários do Brejas. Com 106 votos, o que é quantidade razoável de avaliações, ela ficou com nota 4.7, de um máximo de 5. Nada mal.

Mas este tipo de informação é fácil de obter. O próprio Brejas nos informa isto. Podemos fazer coisas mais interessantes com este conjunto de dados. Por exemplo, qual será o estilo com maiores média e mediana entre os seus rótulos?

dados %>% 
  select(Estilo, Nome, Geral) %>%
  group_by(Estilo) %>%
  summarise(Media=mean(Geral, na.rm=T), Mediana=median(Geral, na.rm=T)) %>%
  arrange(desc(Media))
# A tibble: 86 x 3
Estilo                             Media Mediana
                                 
1  Belgian Quadrupel / ABT          4.22    4.10
2  Bière de Champagne / Bière Brut  4.17    4.20
3  Belgian Dark Strong Ale          4.05    4.05
4  Wood Aged Beer                   4.05    4.20
5  Imperial / Strong Porter         4.03    4.00
6  Russian Imperial Stout           4.03    4.10
7  Belgian Specialty Ale            3.92    3.95
8  Black IPA                        3.91    3.90
9  Imperial / Double IPA            3.91    4.00
10 Oatmeal Stout                    3.90    3.90
# ... with 76 more rows

Note que, no total, 86 estilos de cerveja foram considerados. À primeira vista, o estilo preferido pelos usuários do site é o Belgian Quadrupel / ABT. Entretanto, olhar apenas a média ou a mediana de uma amostra não indica muita coisa. Veja o que acontece quando plotamos os boxplots das avaliações dos estilos de cerveja com as dez maiores médias, ordenados pela mediana:

Perceba que não há nenhuma sugestão de diferença significante entre os grupos. Embora a média da Bière de Champagne / Bière Brut seja 4.17 e da Oatmeal Stout seja 3.90 (quase 7% a mais), não é possível perceber diferença significativa entre estes estilos de bebida. Até poderíamos testar se existe diferença de fato, mas seria perda de tempo.

Relações entre as Características das Cervejas

Outra análise que podemos fazer é verificar as correlações entre as variáveis utilizadas para avaliar as cervejas:

Perceba como Aroma e Sabor estão fortemente correlacionados (0,94), mesma magnitude da correlação entre Sabor e Conjunto. Aroma e Conjunto ficam um pouco atrás, com 0,91.

Aparência e Sensação, apesar de também possuírem alta correlação (0,71), são as duas variáveis menos correlacionadas. Talvez este seja um indicativo de que a Sensação que as cervejas geram em quem as bebe não corresponde à Aparência delas?

Semelhanças entre os Estilos

Uma última análise que podemos fazer é o agrupamento de estilos. Como será que a avaliação dos brasileiros separa os 85 estilos de cerveja analisado aqui? Quais estilos será que estão mais próximos uns dos outros? Note que não estou procurando a similaridade dos estilos entre si, da forma que uma American Pale Ale e uma Blonde Ale são parecidas. Aqui eu agrupei os resultados de acordo com as informações que eu citei anteriormente (a saber, Aroma, Aparência, Sabor, Sensação e Conjunto).

(clique para ampliar)

Este resultado pode ser interpretado como um sistema de recomendação. Se a pessoa gosta do estilo Saison/Farmhouse, é provável que também vá gostar do estilo Rauchbier, pois estes estilos aparecem bem próximos no diagrama acima (procure estes nomes no meio do gráfico, um pouco à esquerda). Por outro lado, uma Rauchbier é bem diferente de uma Lite American Lager (procure no extremo esquerdo do gráfico), pois estão em ramos bem diferentes do diagrama.

Conclusão

Portanto, esta é a análise que realizei a respeito da opinião dos brasileiros sobre cerveja. Não é uma análise completa e exaustiva sobre o assunto. Sequer é representativa da população brasileira, pois apenas a opinião dos cadastrados no site Brejas foi levada em consideração. Ainda assim, creio que ele possa servir como baliza para quem já sabe qual o seu estilo preferido de cerveja e deseja se aventurar experimentando algo diferente, porém similar ao que gosta.

A função de scrap ainda não está perfeita. Existem algumas inconsistências na maneira com que o Brejas exibe os resultados das cervejas e que meu código não conseguiu pegar. Assim, alguns dados estão faltantes. Isto não chega a prejudicar a análise realizada, embora, é claro, dados completos sejam sempre melhores. Assim, fica a sugestão para quem quiser analisar meu código e ver como ele pode ser melhorado.

Como sempre, os códigos usados para obter os dados e para a análise realizada estão no meu github. Utilize este repositório para se inspirar e fazer as suas próprias análises.

Este post foi inspirado por um trabalho realizado pela Kaylin Walker.

Dê um like na fanpage do blog e fique sabendo das próximas atualizações.

]]>
Utilizando Estatística para Decidir qual Cerveja Beber – Parte 1 http://marcusnunes.me/utilizando-estatistica-para-decidir-qual-cerveja-beber-parte-1/ Tue, 27 Feb 2018 11:15:16 +0000 http://marcusnunes.me/?p=440 … ]]> Sou maior de idade, pago meus impostos e contribuo para o PIB. Portanto, nada me impede de ocasionalmente beber uma ou outra cerveja em meus momentos de lazer. Embora eu tenha as minhas preferências pessoais neste assunto, estive pensando qual seria a opinião geral do brasileiro a respeito das cervejas disponíveis no mercado. De acordo com o G1, cada brasileiro consumiu, em média, 60,7 litros de suco de cevada em 2017, o que serve como indicativo do quanto o povo daqui curte uma ampola (ou talvez mais) deste diurético.

Este nível de consumo de cerveja demonstra o interesse da população do nosso país nesta bebida. Assim, acho interessante verificar como os brasileiros avaliam as cervejas consumidas aqui no país. Em vez de tomar uma amostra e sair na rua entrevistando pessoas a este respeito, resolvi utilizar a tecnologia a meu favor.

Existe uma técnica computacional muito utilizada chamada web scraping (raspagem da web). Esta técnica consiste em vasculhar a internet atrás de informações. É o que o Google, por exemplo, usar para indexar os sites em seu mecanismo de busca. Um algoritmo visita automaticamente várias páginas e coleta apenas os dados que são interessantes, a fim de criar um banco de dados para análise ou consulta posterior.

Portanto, se eu conseguisse encontrar algum lugar na internet com as opiniões dos brasileiros sobre cerveja, eu poderia compilá-las em um local e descobrir o que o povo do país pensa sobre os estilos da bebida.

É aí que entra o site Brejas. Ele é uma comunidade alimentada por usuários que consomem as mais variadas cervejas e as avalia de acordo com as seguintes características:

  • Avaliação Geral
  • Aroma
  • Aparência
  • Sabor
  • Sensação
  • Conjunto

Estas avaliações são convertidas em estrelas e são exibidas de forma aberta na internet:

Eisenbahn Strong Golden Ale

Link para a página original da cerveja acima.

Pensando nisso, criei um código no capaz de entrar no site brejas.com.br e baixar as cervejas com o maior número de avaliações recebidas. Por padrão, meu programa baixa as 1000 cervejas com maior número de avaliações. Dividi meu código em três partes, que descrevo abaixo.

A primeira parte do código é uma função chamada scrap, criada justamente para encontrar os links das cervejas mais avaliadas. Como estes links não estão todos na mesma página, é necessário navegar no Brejas para que esta informação seja encontrada.

# funcao para encontrar os links das cervejas com mais 
# avaliacoes no brejas.com.br

scrap <- function(url){

  pagina <- read_html(url)

  # filtragem dos links

  links <- html_attr(html_nodes(pagina, "a"), "href")
  links <- links[grep("/cerveja/", links)]
  links <- links[grep("#", links, invert=TRUE)]
  links <- links[grep("www", links, invert=TRUE)]

  # manter apenas os que mais se repetem

  links <- names(sort(table(links), decreasing=TRUE)[1:10])

  # criar os links completos

  links <- paste("http://www.brejas.com.br", links, sep="")

  return(links)

}

A segunda parte do código depende da primeira. A função cerveja toma os links obtidos anteriormente e baixa as informações que servem para avaliar as cervejas.

# funcao para extrair as informacoes de uma cerveja 
# do brejas.com.br a partir de um link

cerveja <- function(url){
  
  pagina <- read_html(url)
  
  # nome da cerveja
  
  nome <- pagina %>% 
    html_nodes(xpath="/html/body/div[2]/div[2]/div/main/article/div/div/h1/span[1]") %>%
    html_text()
  
  # informacoes
  
  informacoes <- pagina %>% 
    html_nodes(xpath="/html/body/div[2]/div[2]/div/main/article/div/div/div[8]/div") %>%
    html_text()
  
  if (length(informacoes)==0){
    informacoes <- pagina %>% 
      html_nodes(xpath="/html/body/div[2]/div[2]/div/main/article/div/div/div[7]/div") %>%
      html_text()
  }
  
  cervejaria <- gsub("InformaçõesCervejaria", "", strsplit(informacoes, split="Grupo")[[1]][1])
  
  grupo <- strsplit(strsplit(informacoes, split="Grupo")[[1]][2], split="Estilo")[[1]][1]
  
  estilo <- strsplit(strsplit(informacoes, split="Estilo")[[1]][2], split="Álcool")[[1]][1]
  
  ativa <- strsplit(strsplit(informacoes, split="Ativa")[[1]][2], split="Sazonal")[[1]][1]
  
  sazonal <- strsplit(strsplit(informacoes, split="Sazonal")[[1]][2], split="Temperatura")[[1]][1]
  
  copo <- strsplit(strsplit(informacoes, split="Copo ideal")[[1]][2], split="Visite")[[1]][1]
  
  numeros <- str_extract_all(informacoes, "\\(?[0-9,.]+\\)?")[[1]]
  numeros <- numeros[grep(",", numeros, invert=TRUE)]
  numeros <- as.numeric(numeros)
  alcool  <- numeros[1]
  t.min   <- numeros[2]
  t.max   <- numeros[3]
  
  # scores

  dados <- pagina %>% 
    html_nodes(xpath="/html/body/div[2]/div[2]/div/main/article/div/div/div[15]/div[3]/div/div[1]/div[2]/div/div[1]") %>%
    html_text()
  
  if (length(dados) == 0){
    dados <- pagina %>% 
      html_nodes(xpath="/html/body/div[2]/div[2]/div/main/article/div/div/div[16]/div[3]/div/div[1]/div[2]/div/div[1]") %>%
      html_text()
  }
  
  if (length(dados) == 0) {
    resultado <- data.frame(Nome=nome,
                            Cervejaria=cervejaria,
                            Grupo=grupo,
                            Estilo=estilo,
                            Alcool=alcool,
                            Ativa=ativa,
                            Sazonal=sazonal,
                            Minima=t.min,
                            Maxima=t.max,
                            Copo=copo,
                            Geral=NA,
                            Aroma=NA,
                            Aparencia=NA,
                            Sabor=NA,
                            Sensacao=NA,
                            Conjunto=NA,
                            Votos=NA)
  } else {
  
  # regex para extrair apenas os numeros

    avaliacao <- str_extract_all(dados, "\\(?[0-9,.]+\\)?")[[1]]
    avaliacao <- avaliacao[c(1, 2, 5, 8, 11, 14, 4)]
    avaliacao <- as.numeric(gsub("\\((.+)\\)","\\1", avaliacao))#/c(1, 10, 5, 20, 5, 10, 1)
  
    # organizar as informacoes
  
    resultado <- data.frame(Nome=nome,
                          Cervejaria=cervejaria,
                          Grupo=grupo,
                          Estilo=estilo,
                          Alcool=alcool,
                          Ativa=ativa,
                          Sazonal=sazonal,
                          Minima=t.min,
                          Maxima=t.max,
                          Copo=copo,
                          Geral=avaliacao[1],
                          Aroma=avaliacao[2],
                          Aparencia=avaliacao[3],
                          Sabor=avaliacao[4],
                          Sensacao=avaliacao[5],
                          Conjunto=avaliacao[6],
                          Votos=avaliacao[7])
  
  }

  return(resultado)
}

Por fim, é preciso juntar estas duas funções para que tudo dê certo:

# pacotes necessarios

library(rvest)
library(httr)
library(stringr)
library(tidyverse)

# funcoes para obter os dados

source("cerveja.R")
source("scrap.R")

# funcoes para obter os dados

source("cerveja.R")
source("scrap.R")

####################################
### baixar os dados para analise ###
####################################

# baixar os links das 10*k cervejas mais avaliadas

links <- scrap("http://www.brejas.com.br/cerveja/mais-avaliadas?page=1")

k <- 100

for (j in 2:k){
  url <- paste("http://www.brejas.com.br/cerveja/mais-avaliadas?page=", j, sep="")
  links <- c(links, scrap(url))
}

links <- sort(links)

dados <- cerveja(links[1])

for (j in links[c(-1)]){
  dados <- rbind(dados, cerveja(j))
}

# remove espacos ao final dos nomes

dados$Estilo <- trimws(dados$Estilo, "right")

Meu computador levou 42 minutos para baixar os dados de 1000 cervejas. Ou seja, na média, as informações de cada cerveja levaram aproximadamente 2,5 segundos para serem coletadas. Talvez seja um desempenho um pouco lento, mas não é nada mal para um código não muito otimizado.

Agora que os dados foram baixados, basta proceder com a análise. Mas isto é um papo para um outro post.

Os códigos usados para obter os dados e para a análise realizada estão no meu github.

Este post foi inspirado por um trabalho realizado pela Kaylin Walker.

Dê um like na fanpage do blog e fique sabendo das próximas atualizações.

]]>
Teria sido possível evitar o desastre da Challenger? http://marcusnunes.me/teria-sido-possivel-evitar-o-desastre-da-challenger/ Thu, 15 Feb 2018 12:04:11 +0000 http://marcusnunes.me/?p=381 … ]]> Creio que as duas imagens mais marcantes em toda a história do programa espacial norte-americano sejam a caminhada de Neil Armostrong na Lua e a explosão do ônibus espacial Challenger. Esta tragédia, exibida ao vivo pela TV em 28 de janeiro de 1986, chocou o mundo.

Após uma cuidadosa investigação, a NASA concluiu que a explosão ocorreu devido ao mau funcionamento de uma peça chamada O-ring, que deveria manter a junção entre as partes dos foguetes que levariam a Challenger para o espaço. Mas será que o problema com estas peças não poderia ter sido previsto utilizando dados dos outros lançamentos de ônibus espaciais?

A Challenger foi a 25a missão oficial de um ônibus espacial. Para fazer este estudo, utilizei os dados de temperatura e falhas de O-rings de 23 voos de ônibus espaciais anteriores ao da Challenger, obtidos no UCI Machine Learning Repository. Apenas os dados de 23 dos 24 voos anteriores estão disponíveis publicamente.

O gráfico abaixo mostra, no eixo horizontal, as temperaturas de lançamento, em graus Celsius, durante o lançamento dos ônibus espaciais. No eixo vertical, 0 significa que não houve problemas com nenhum O-ring durante o lançamento do ônibus espacial naquela temperatura e 1 significa que houve algum problema com pelo menos um O-ring durante o lançamento.

Perceba que, aparentemente, há influência da temperatura no comportamento dos O-rings. Quanto mais frio, é mais provável que haja algum problema com o dispositivo. Mas estatística não é achismo e há uma maneira de testar se esta hipótese é verdadeira. Para isto, utilizei uma ferramenta chamada regressão logística. O R, software que utilizo no meu dia a dia, possui um comando específico para isto, chamado glm. A resposta que obtive está logo abaixo:

  Call:
glm(formula = falha ~ temperatura, family = binomial, data = dados)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.0611  -0.7613  -0.3783   0.4524   2.2175  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)  
(Intercept)   7.6137     3.9334   1.936   0.0529 .
temperatura  -0.4179     0.1948  -2.145   0.0320 *
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 28.267  on 22  degrees of freedom
Residual deviance: 20.315  on 21  degrees of freedom
AIC: 24.315

Number of Fisher Scoring iterations: 5

Mas o que este monte de números quer realmente dizer? Vejamos como a curva dada pelo output acima se ajusta à realidade:

Nesta figura, além do eixo y indicar se houve ou não algum problema com os o-rings, ele indica a probabilidade de haver um acidente dada a temperatura do local do lançamento do ônibus espacial. No dia do lançamento da Challenger, a temperatura estava prevista para 31°F (equivalente a -0,5ºC). Até então, esta seria a temperatura mais baixa de lançamento de um ônibus espacial. Substituindo um valor próximo a este e outros no modelo ajustado acima, temos as seguintes probabilidades de falha do o-ring:

  temperatura probabilidade
1           0  0.9995065985
2           5  0.9960269060
3          10  0.9687735209
4          15  0.7933601306
5          20  0.3220940541
6          25  0.0555337160
7          30  0.0072240135
8          35  0.0008996910
9          40  0.0001114276

Note que, para temperaturas próximas de zero, a probabilidade de falha é muito próxima de 1. Ou seja, a chance de falha é de quase 100%! Se a temperatura estivesse mais alta, acima de 25 graus, esta probabilidade cairia para 0,055 (puco mais de 5%). Ou seja, a falha do equipamento era quase uma certeza.

Por si só, a falha de um ou mais O-rings não acarretaria na explosão da nave. Entretanto, não era necessário arriscar a vida de sete astronautas e um equipamento caríssimo num lançamento muito propenso a ter problemas. Bastaria esperar alguns dias por condições mais propícias para este realizar este evento.

Os arquivos e códigos utilizados nesta análise podem ser encontrados no meu github.

]]>
Natal ou Porto Alegre: Onde o Verão é Mais Quente? http://marcusnunes.me/natal-ou-porto-alegre-onde-o-verao-e-mais-quente/ Tue, 06 Feb 2018 16:01:41 +0000 http://marcusnunes.me/?p=363 … ]]> Um Pouco de História

Eu moro em Natal, RN, mas sou natural de São Leopoldo, RS. Também sou professor de Estatística. Quando falo de análise de dados com meus alunos, tem uma afirmação minha da qual eles sempre duvidam: Porto Alegre é mais quente do que Natal no verão.

Só quem morou no sul e sudeste, em cidades com clima subtropical e afetadas pela continentalidade, sabem do que estou falando. Embora nossa memória nos traia às vezes, sempre tive a impressão de que os verões em Porto Alegre são muito mais quentes do que os verões aqui em Natal.

Para provar ou desprovar esta afirmação, baixei os dados do BDMEP – Banco de Dados Meteorológicos para Ensino e Pesquisa referentes à temperatura máxima diária em Natal e Porto Alegre entre 1 de janeiro de 2002 e 31 de dezembro de 2016. Ou seja, são 15 anos de dados de temperatura diária nestas duas cidades que irão sustentar (ou não) minha afirmação.

Análise Descritiva

Abaixo vemos todas as observações disponíveis para as temperaturas das duas cidades:

Este gráfico, que possui informação desde 1961, não ficou bom. Faltam muitos dados dos anos 70 e 80, além de algumas informações do início dos anos 2000. Por isso, resolvi manter apenas os dados de 1 de janeiro de 2002 em diante:

Pronto. Melhor agora.

Podemos ver claramente no gráfico como Porto Alegre tem dias mais quentes do que Natal, principalmente no início do ano, na época do verão. Mas a quantidade deles é muito inferior ao que eu me lembro. Algo não parece certo.

Mas este gráfico mostra as temperaturas médias diárias. Acontece que Porto Alegre tem uma amplitude de temperatura muito alta, inclusive no verão. Os dias começam frescos, mas acabam esquentando muito. Por isso refiz os gráficos, agora considerando a temperatura máxima atingida no dia:

Bingo! A quantidade de dias de calor intenso em Porto Alegre, com a máxima passando dos 35ºC, é muito maior do que em Natal. Inclusive, Natal não teve um dia sequer, nos últimos 15 anos, em que a temperatura máxima passou dos 35ºC.

Portanto, como eu lembrava, Porto Alegre é uma cidade muito mais quente do que Natal no verão.

Mais detalhes a respeito desta análise, como seu o código e os dados utilizados nela, estão na minha página no github.

]]>
Intervalos de Confiança na Prática http://marcusnunes.me/intervalos-de-confianca-na-pratica/ Fri, 02 Feb 2018 12:54:46 +0000 http://marcusnunes.me/?p=395 … ]]> A construção de Intervalos de Confiança é bastante simples. Entretanto, seu conceito nem sempre é entendido por quem trabalha com eles, principalmente os iniciantes. Pensando nisso, desenvolvi um aplicativo capaz de simplificar o entendimento do processo.

Segundo o livro Estatística Básica (Bussab e Morettin, 2014), a definição de intervalo de confiança a 95% para o parâmetro da média populacional µ, quando a variância populacional σ² é conhecida, é dada por

Se pudéssemos construir uma quantidade grande de intervalos aleatórios da forma

[latex](\overline{X}-1,96\sigma_{\overline{X}}, \overline{X}+1,96\sigma_{\overline{X}}),[/latex]

todos baseados em amostras de tamanho n, 95% deles conteriam o parâmetro µ.

Ou seja, por esta definição, não temos a garantia de que o verdadeiro parâmetro µ estará dentro do intervalo de confiança calculado com 95% de chance. A única certeza que temos é que, se repetirmos o procedimento de construção do intervalo de confiança um número grande de vezes, 95% deles vão conter o parâmetro µ.

Logicamente, isto significa que 5% dos intervalos de confiança calculados não possuem o verdadeiro parâmetro de interesse da população estudada. O problema é que nunca sabemos que intervalos de confiança são estes.

Embora eu tenha criado o aplicativo apenas para o parâmetro µ, a lógica acima vale para a construção de qualquer intervalo de confiança.

Experimente o aplicativo por si mesmo e veja se ficou clara como a construção de intervalos de confiança é definida. O código utilizado para criar o aplicativo pode ser encontrado no meu github.

]]>
Visualização Gráfica e Resumida dos Resultados das Edições do ENEM nos Anos de 2010 a 2015 http://marcusnunes.me/visualizacao-grafica-e-resumida-dos-resultados-das-edicoes-do-enem-nos-anos-de-2010-a-2015/ Sun, 21 Jan 2018 13:21:27 +0000 http://marcusnunes.me/?p=412 … ]]> Analisar os resultados do ENEM é uma tarefa difícil. Embora os microdados estejam disponíveis gratuitamente para quem quiser baixá-los, nem todos possuem o conhecimento técnico necessário para analisá-los a partir do zero. Até mesmo pesquisadores experientes precisam pedir ajuda para realizar esta tarefa.

Pensando neste problema, orientei uma monografia no Departamento de Estatística da UFRN chamada Visualização dos resultados das edições de 2010 a 2015 do ENEM através de um Shiny App, de autoria de Marylaine Nascimento. Esta monografia se propôs a analisar, utilizando Estatística Descritiva, os resultados das últimas seis edições do ENEM disponíveis no site do INEP. Além da monografia, um aplicativo foi criado, a fim de tornar mais acessível a pesquisa realizada.

Antes de realizar a análise, os milhões de microdados do ENEM entre 2010 e 2015 foram processados, a fim de que apenas as informações mais fundamentais sobre eles pudessem ser extraídas. Desta forma, gráficos que levavam mais de dez minutos para ficarem prontos passaram a levar menos de três segundos para serem completados. Um dos gráficos criados está logo abaixo. Ele compara o resultado geral do ENEM em 2015, separado por região do Brasil:

No total, o aplicativo apresenta 420 gráficos diferentes, além de tabelas e estatísticas sobre os resultados do ENEM entre 2010 e 2015. Qualquer pessoa é capaz de explorar os resultados do ENEM para as variáveis que escolhemos representar no aplicativo desenvolvido.

Ainda há um pequeno bug que faz com que o primeiro gráfico gerado pelo usuário demore em torno de um minuto para aparecer na tela. Este bug ocorre apenas com o primeiro gráfico: todos os outros são gerados instantaneamente. Estamos trabalhando para corrigir isto e, em breve, todos os gráficos aparecerão com a mesma velocidade.

Os arquivos com o código deste aplicativo estão disponíveis no github da Marylaine Nascimento.

]]>
Apresentação http://marcusnunes.me/apresentacao/ Mon, 01 Jan 2018 16:11:40 +0000 http://marcusnunes.me/?p=368 … ]]> Este blog foi pensado como uma página de divulgação científica. Nele publicarei pequenas análises ou ferramentas estatísticas, em geral envolvendo assuntos que considero interessantes. Não serão análises acadêmicas. A ideia principal é que sejam assuntos interessantes, com algum apelo para curiosos, e fácil de serem compreendidas.

Se houver dúvida ou pergunto sobre algum assunto tratado aqui, por favor entre em contato comigo através deste formulário.

]]>