# Dados do experimento
k <- 6 # águas observadas
n <- 9 # total de lançamentos
# Verossimilhança em um único ponto: P(k=6 | n=9, p=0.70)
dbinom(6, size = 9, prob = 0.70)
# Grade de valores de p em [0, 1]
p_grid <- seq(0, 1, length.out = 100)
# Verossimilhança em cada ponto da grade
likelihood <- dbinom(k, size = n, prob = p_grid)
# Gráfico da curva de verossimilhança
plot(p_grid, likelihood, type = "l", lwd = 2,
xlab = "p (proporção de oceano)", ylab = "Verossimilhança",
main = "Verossimilhança binomial — k=6, n=9")Prática em R - Aula 03
Modelos generativos e a aproximação por grade
1 Verossimilhança binomial com dbinom() e pbinom()
O experimento da atirada de globo consiste em lançar um globo terrestre ao ar e registrar se o dedo indicador pousa sobre água (W) ou terra (T) ao capturá-lo (McElreath 2020). O objetivo é estimar a proporção \(p\) de oceano na superfície terrestre. Um experimento com nove lançamentos produziu a sequência:
\[\text{W, T, W, W, W, T, W, T, W}\]
O total é \(k = 6\) águas em \(n = 9\) lançamentos. Nesta seção, usamos dbinom() para calcular a verossimilhança binomial em diferentes valores de \(p\) e construir a curva de verossimilhança. Em seguida, usamos pbinom() para calcular probabilidades acumuladas.
Código
Código
# P(K >= 6 | n=9, p=0.70): probabilidade de observar 6 ou mais águas com p=0,70
1 - pbinom(5, size = 9, prob = 0.70)
# O mesmo resultado com p=0,50: seria o valor observado incomum?
1 - pbinom(5, size = 9, prob = 0.50)2 O modelo como gerador de dados com rbinom()
A função rbinom() usa o modelo binomial como um modelo generativo: dado um valor de \(p\), ela simula realizações do experimento. Nesta seção, iremos gerar mil experimentos de nove lançamentos com \(p = 0{,}70\) e comparar a distribuição das contagens simuladas com o valor observado \(k = 6\).
Código
# Simular 1000 experimentos de 9 lançamentos com p fixo em 0,70
k_simulado <- rbinom(1000, size = 9, prob = 0.70)
# Histograma das contagens simuladas
hist(k_simulado, breaks = -0.5 + (0:10),
xlab = "Número de águas em 9 lançamentos",
ylab = "Frequência",
main = "Simulação: 1000 experimentos com p = 0,70")
abline(v = 6, col = "red", lwd = 2) # valor observadoCódigo
# Comparar histogramas com diferentes valores de p
par(mfrow = c(1, 3))
for (p_val in c(0.30, 0.50, 0.70)) {
k_sim <- rbinom(1000, size = 9, prob = p_val)
hist(k_sim, breaks = -0.5 + (0:10),
xlab = "Número de águas",
ylab = "Frequência",
main = paste("p =", p_val),
xlim = c(0, 9))
abline(v = 6, col = "red", lwd = 2)
}
par(mfrow = c(1, 1))3 Checagem preditiva a priori
A checagem preditiva a priori combina simulação com a distribuição a priori sobre \(p\): em vez de fixar \(p\) em um único valor, amostramos \(p\) da distribuição a priori e, para cada valor amostrado, simulamos um experimento de nove lançamentos. O resultado é uma distribuição das contagens que o modelo espera ver antes de observar qualquer dado real.
Código
# Checagem preditiva a priori com distribuição a priori uniforme
p_amostrado <- runif(1000, min = 0, max = 1) # amostrar p da priori uniforme
k_pred_unif <- rbinom(1000, size = 9, prob = p_amostrado)
hist(k_pred_unif, breaks = -0.5 + (0:10),
xlab = "Número de águas simuladas",
ylab = "Frequência",
main = "Checagem preditiva a priori — distribuição a priori uniforme")
abline(v = 6, col = "red", lwd = 2) # valor observadoCódigo
# Checagem preditiva a priori com distribuição a priori informativa
p_amostrado_info <- runif(1000, min = 0.60, max = 0.80)
k_pred_info <- rbinom(1000, size = 9, prob = p_amostrado_info)
par(mfrow = c(1, 2))
hist(k_pred_unif, breaks = -0.5 + (0:10),
xlab = "Número de águas simuladas", ylab = "Frequência",
main = "Priori uniforme [0, 1]", xlim = c(0, 9))
abline(v = 6, col = "red", lwd = 2)
hist(k_pred_info, breaks = -0.5 + (0:10),
xlab = "Número de águas simuladas", ylab = "Frequência",
main = "Priori informativa [0.60, 0.80]", xlim = c(0, 9))
abline(v = 6, col = "red", lwd = 2)
par(mfrow = c(1, 1))4 Aproximação por grade
A aproximação por grade substitui o intervalo contínuo \(p \in [0, 1]\) por um conjunto finito de pontos igualmente espaçados. Em cada ponto da grade, calcula-se a verossimilhança e o produto verossimilhança \(\times\) distribuição a priori. A normalização desse produto gera uma distribuição discreta que aproxima a distribuição a posteriori contínua.
4.1 Distribuição a priori uniforme
Código
# Grade com 100 pontos em [0, 1]
p_grid <- seq(0, 1, length.out = 100)
k <- 6; n <- 9
# Passo 1: verossimilhança em cada ponto
likelihood <- dbinom(k, size = n, prob = p_grid)
# Passo 2: distribuição a priori uniforme e produto
prior_unif <- rep(1, 100) # todos os pontos com o mesmo peso
peso_unif <- prior_unif * likelihood
# Passo 3: normalização
posterior_unif <- peso_unif / sum(peso_unif)
# Gráfico da distribuição a posteriori
plot(p_grid, posterior_unif, type = "l", lwd = 2,
xlab = "p (proporção de oceano)",
ylab = "Probabilidade a posteriori",
main = "Distribuição a posteriori — distribuição a priori uniforme")
abline(v = k / n, lty = 2, col = "gray40")4.2 Efeito da resolução da grade
Código
# Comparação da distribuição a posteriori com diferentes resoluções de grade
par(mfrow = c(2, 2))
for (n_pts in c(5, 10, 20, 100)) {
pg <- seq(0, 1, length.out = n_pts)
lik <- dbinom(k, size = n, prob = pg)
post <- lik / sum(lik) # distribuição a priori uniforme: post proporcional a lik
plot(pg, post, type = "b", pch = 19,
main = paste("Grade com", n_pts, "pontos"),
xlab = "p", ylab = "Probabilidade a posteriori")
}
par(mfrow = c(1, 1))4.3 Distribuição a priori uniforme versus informativa
Código
p_grid <- seq(0, 1, length.out = 100)
k <- 6; n <- 9
# Verossimilhança
likelihood <- dbinom(k, size = n, prob = p_grid)
# Distribuição a priori uniforme
prior_unif <- rep(1, 100)
posterior_unif <- prior_unif * likelihood
posterior_unif <- posterior_unif / sum(posterior_unif)
# Distribuição a priori informativa: zero abaixo de p = 0,50
prior_info <- ifelse(p_grid < 0.5, 0, 1)
posterior_info <- prior_info * likelihood
posterior_info <- posterior_info / sum(posterior_info)
# Gráfico comparativo
plot(p_grid, posterior_unif, type = "l", lwd = 2, col = "steelblue",
xlab = "p (proporção de oceano)",
ylab = "Probabilidade a posteriori",
main = "Distribuição a priori uniforme vs. informativa",
ylim = c(0, max(posterior_unif, posterior_info)))
lines(p_grid, posterior_info, col = "red", lwd = 2)
abline(v = k / n, lty = 2, col = "gray40")
legend("topleft",
legend = c("Priori uniforme", "Priori informativa (p >= 0,5)"),
col = c("steelblue", "red"), lwd = 2, bty = "n")