“The greatest value of a picture is when it forces us to notice what we never expected to see.” John W. Tukey
John Wilder Tukey foi um grande estatístico. Ele foi o primeiro a utilizar o termo “análise exploratória de dados”. Sua afirmação de que a “visualização nos força a perceber o que nunca esperaríamos ver” é de extrema importância.
Francis Anscombe, outro grande estatístico, ajudou a derrubar a premissa de que “cálculos numéricos são exatos, mas gráficos são complicados”.
Na realidade, sabe-se que ambos são importantes, tanto as estatísticas quanto os gráficos, porém as visualizações podem “nos ajudar perceber e apreciar algumas características gerais dos dados” além disso nos permitem “olhar para trás e ver que mais caracterististicas estão lá.” Anscombe disse isso em 1973, no artigo “Graphs in Statistical Analysis” muito antes da revolução da computação que vemos hoje.
Os dados de Anscombe são usados justamente para mostrar que muitas vezes as estatísticas não bastam e que gerar visualizações são fundamentais para corroborar os resultados das análises.
Vamos aqui fazer uma breve análise desses dados e mostrar que não podemos negligenciar a visualização.
Anscombe construiu 4 conjuntos de dados(I-IV) divididos em x e y:
Esses quatro conjuntos de dados bidimensionais simples (cada um com 11 linhas) têm propriedades estatísticas semelhantes, mas histórias diferentes para contar… Veremos isso melhor utilizando o R.
Esse conjunto de dados, é nativo do R, para vermos como ele aparece basta digitar o simples código abaixo:
anscombe
## x1 x2 x3 x4 y1 y2 y3 y4
## 1 10 10 10 8 8.04 9.14 7.46 6.58
## 2 8 8 8 8 6.95 8.14 6.77 5.76
## 3 13 13 13 8 7.58 8.74 12.74 7.71
## 4 9 9 9 8 8.81 8.77 7.11 8.84
## 5 11 11 11 8 8.33 9.26 7.81 8.47
## 6 14 14 14 8 9.96 8.10 8.84 7.04
## 7 6 6 6 8 7.24 6.13 6.08 5.25
## 8 4 4 4 19 4.26 3.10 5.39 12.50
## 9 12 12 12 8 10.84 9.13 8.15 5.56
## 10 7 7 7 8 4.82 7.26 6.42 7.91
## 11 5 5 5 8 5.68 4.74 5.73 6.89
A diferença da tabela anterior é que ela não está separada como na primeira tabela em 4 conjuntos, além disso, não está na mesma ordem. Vamos primeiro reordenar os dados usando a função select da biblioteca dplyr:
# Reorder by column name
library(dplyr)
Anscombe_data <-data.frame( anscombe%>% select(x1,y1,x2,y2,x3,y3,x4,y4))
Anscombe_data
## x1 y1 x2 y2 x3 y3 x4 y4
## 1 10 8.04 10 9.14 10 7.46 8 6.58
## 2 8 6.95 8 8.14 8 6.77 8 5.76
## 3 13 7.58 13 8.74 13 12.74 8 7.71
## 4 9 8.81 9 8.77 9 7.11 8 8.84
## 5 11 8.33 11 9.26 11 7.81 8 8.47
## 6 14 9.96 14 8.10 14 8.84 8 7.04
## 7 6 7.24 6 6.13 6 6.08 8 5.25
## 8 4 4.26 4 3.10 4 5.39 19 12.50
## 9 12 10.84 12 9.13 12 8.15 8 5.56
## 10 7 4.82 7 7.26 7 6.42 8 7.91
## 11 5 5.68 5 4.74 5 5.73 8 6.89
Agora temos os dados ordenados!
Para melhorar a visualização, vamos colocar esses dados numa tabela usando a biblioteca DT usada para fazer belas tabelas em dashboards no shiny ou no Rmarkdown, aliás recomendo estudar esse pacote se você quiser ou precisar fazer tabelas profissionais no R.
library(DT)
datatable(Anscombe_data,
options = list(dom = 'tip', paging = FALSE ))
Vamos fazer nossa análise dos dados bidimensionais \((x_1,y_1), (x_2,y_2), (x_3,y_3), (x_4,y_4)\).
Vamos as estatísticas
Abaixo o código para calcular a média de todas as colunas
round(apply(Anscombe_data, 2, mean),2)
## x1 y1 x2 y2 x3 y3 x4 y4
## 9.0 7.5 9.0 7.5 9.0 7.5 9.0 7.5
Abaixo o código para calcular o desvio padrão de todas as colunas
round(apply(Anscombe_data, 2, sd),2)
## x1 y1 x2 y2 x3 y3 x4 y4
## 3.32 2.03 3.32 2.03 3.32 2.03 3.32 2.03
Abaixo o código para calcular a correlação de cada par \((x,y)\):
df<-data.frame(cor(Anscombe_data$x1, Anscombe_data$y1), cor(Anscombe_data$x2, Anscombe_data$y2), cor(Anscombe_data$x3, Anscombe_data$y3), cor(Anscombe_data$x4, Anscombe_data$y4))
colnames(df)<- c('cor(x1,y1)', 'cor(x2,y2)', 'cor(x3,y3)', 'cor(x4,y4)')
df
## cor(x1,y1) cor(x2,y2) cor(x3,y3) cor(x4,y4)
## 1 0.8164205 0.8162365 0.8162867 0.8165214
Observando os cálculos temos as seguintes conclusões:
Como ocorreu uma correlação forte em todos os pares, vamos estimar modelos de regressão para cada um.
Para fazer isso no R, usamos a função lm e escrevemos lm(y~x, data) se quisermos um modelo de y em função de x do dataframe data.
Vamos então criar 4 modelos, um para cada par \((x,y)\):
model_1 <- lm(y1~x1, data = Anscombe_data)
model_2 <- lm(y2~x2, data=Anscombe_data)
model_3 <- lm(y3~x3, data = Anscombe_data)
model_4 <- lm(y4~x4, data = Anscombe_data)
O código acima gerou os 4 modelos. Agora podemos olhar os coeficientes dos modelos. Para isso usaremos a função summary para cada um dos modelos:
summary(model_1)
##
## Call:
## lm(formula = y1 ~ x1, data = Anscombe_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.92127 -0.45577 -0.04136 0.70941 1.83882
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.0001 1.1247 2.667 0.02573 *
## x1 0.5001 0.1179 4.241 0.00217 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.237 on 9 degrees of freedom
## Multiple R-squared: 0.6665, Adjusted R-squared: 0.6295
## F-statistic: 17.99 on 1 and 9 DF, p-value: 0.00217
summary(model_2)
##
## Call:
## lm(formula = y2 ~ x2, data = Anscombe_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.9009 -0.7609 0.1291 0.9491 1.2691
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.001 1.125 2.667 0.02576 *
## x2 0.500 0.118 4.239 0.00218 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.237 on 9 degrees of freedom
## Multiple R-squared: 0.6662, Adjusted R-squared: 0.6292
## F-statistic: 17.97 on 1 and 9 DF, p-value: 0.002179
summary(model_3)
##
## Call:
## lm(formula = y3 ~ x3, data = Anscombe_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.1586 -0.6146 -0.2303 0.1540 3.2411
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.0025 1.1245 2.670 0.02562 *
## x3 0.4997 0.1179 4.239 0.00218 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.236 on 9 degrees of freedom
## Multiple R-squared: 0.6663, Adjusted R-squared: 0.6292
## F-statistic: 17.97 on 1 and 9 DF, p-value: 0.002176
summary(model_4)
##
## Call:
## lm(formula = y4 ~ x4, data = Anscombe_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.751 -0.831 0.000 0.809 1.839
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.0017 1.1239 2.671 0.02559 *
## x4 0.4999 0.1178 4.243 0.00216 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.236 on 9 degrees of freedom
## Multiple R-squared: 0.6667, Adjusted R-squared: 0.6297
## F-statistic: 18 on 1 and 9 DF, p-value: 0.002165
Observando os coeficientes de todos os modelos podemos concluir que:
Aparentemente temos ótimos modelos de regressão. Vamos agora então visualizar cada par de dados num gráfico de dispersão junto com a sua respectiva regressão que estimamos:
Vamos
library(ggplot2)
#plot1
plot1 <- ggplot(Anscombe_data, aes(x=x1, y=y1)) + geom_point(size=2,fill= 'blue', pch=21) +
geom_abline(intercept = model_1$coefficients[1], slope = model_1$coefficients[2]) + ggtitle('Conjunto I')
plot1
#plot2
plot2 <- ggplot(Anscombe_data, aes(x=x2, y=y2)) + geom_point(size=2,fill= 'blue', pch=21) +
geom_abline(intercept = model_2$coefficients[1], slope = model_2$coefficients[2]) + ggtitle('Conjunto II')
plot2
#plot3
plot3 <- ggplot(Anscombe_data, aes(x=x3, y=y3)) + geom_point(size=2,fill= 'blue', pch=21) +
geom_abline(intercept = model_3$coefficients[1], slope = model_3$coefficients[2]) + ggtitle('Conjunto III')
plot3
#plot4
plot4 <- ggplot(Anscombe_data, aes(x=x4, y=y4)) + geom_point(size=2,fill= 'blue', pch=21) +
geom_abline(intercept = model_4$coefficients[1], slope = model_4$coefficients[2]) + ggtitle('Conjunto IV')
plot4
Já deu para perceber que cada conjunto é muito diferente apesar de suas estatísticas coincidirem. Para melhorar a comparação de todas as visualizações, vamos colocá-los lado a lado numa mesma visualização. Para isso vamos usar a função ggarrange do pacote ggpubr:
library(ggpubr)
## Loading required package: magrittr
ggarrange(plot1, plot2, plot3, plot4 , ncol = 2, nrow = 2)
Percebe-se também que o modelo de regressão gerado não é um bom modelo para todos os conjuntos.
Logo, apesar de
Os dados são muitos diferentes e isso só foi possível de perceber após visualizarmos os dados. Por isso não esqueça, sempre que possível visualize seus dados. Use sempre junto dos cálculos e análises estatísticas as visualizações para não tirar conclusões precipitadas.
Era isso espero que tenha aprendido algo novo!
Keep calm and analysing data!