En clase, hemos visto como ajustar un modelo de regresión lineal a los datos de velocidades y distancias necesarias para para unos coches. Ahora ilustramos como usar para hacer el ajuste bayesiano. Primero vemos el ajuste clásico.
data(cars)
modelolineal <- lm(dist ~ speed, data=cars)
print(modelolineal)
##
## Call:
## lm(formula = dist ~ speed, data = cars)
##
## Coefficients:
## (Intercept) speed
## -17.579 3.932
plot(cars)
abline(modelolineal,col='red',lwd=2)
xnuevo <- data.frame(20)
names(xnuevo) <- "speed"
predict(modelolineal,xnuevo,interval="confidence")
## fit lwr upr
## 1 61.06908 55.24729 66.89088
predict(modelolineal,xnuevo,interval="prediction")
## fit lwr upr
## 1 61.06908 29.60309 92.53507
Podemos construir un modelo de regresión utilizando un doodle en OpenBUGS.
Para correrlo en R, primero escribimos una función con el código del modelo.
modelobayes <- function(){
for( i in 1 : n ) {
dist[i] ~ dnorm(mu[i], phi)
mu[i] <- beta0 + beta1 * speed[i]
}
beta0 ~ dnorm(0.0, 1.0E-6)
beta1 ~ dnorm(0.0, 1.0E-6)
phi ~ dgamma(0.001, 0.001)
sigma2 <- 1 / phi
}
Para correr el programa a través de R, es necesario definir los datos en forma de una lista.
datos <- list(n=length(cars$dist),dist=cars$dist,speed=cars$speed)
Metemos los valores iniciales en otra lista dentro de una función.
iniciales <- function(){
list(beta0=0,beta1=0,phi=1)
}
Ya llamamos a y usamos el comando para ejecutar el programa. El código corre 10000 iteraciones en equilibrio y 5000 de burnin.
library(R2OpenBUGS)
resultados <- bugs(data = datos, inits = iniciales, parameters.to.save = c("beta0",
"beta1", "phi","sigma2"), model.file = modelobayes, n.chains = 1, n.iter = 10000)
Podemos obtener un breve resumen de los resultados.
resultados
## Inference for Bugs model at "C:/Users/mwiper/AppData/Local/Temp/RtmpWafHvR/model2cac5e14983.txt",
## Current: 1 chains, each with 10000 iterations (first 5000 discarded)
## Cumulative: n.sims = 5000 iterations saved
## mean sd 2.5% 25% 50% 75% 97.5%
## beta0 -18.1 7.1 -32.3 -22.6 -18.0 -13.4 -4.3
## beta1 4.0 0.4 3.1 3.7 4.0 4.2 4.8
## phi 0.0 0.0 0.0 0.0 0.0 0.0 0.0
## sigma2 247.2 53.9 163.1 210.1 240.1 277.5 368.8
## deviance 416.4 2.6 413.4 414.5 415.7 417.5 423.1
##
## DIC info (using the rule, pD = Dbar-Dhat)
## pD = 3.2 and DIC = 419.5
## DIC is an estimate of expected predictive error (lower deviance is better).
En este caso, las estimaciones medias de los regresores son parecidas a las frecuentistas.
Podemos analizar los resultados a través del paquete , pero es casi más fácil hacerlo directamente, sacando los datos generados por el MCMC en R.
names(resultados$sims.list)
## [1] "beta0" "beta1" "phi" "sigma2" "deviance"
beta0 <- resultados$sims.list$beta0
beta1 <- resultados$sims.list$beta1
phi <- resultados$sims.list$phi
sigma2 <- resultados$sims.list$sigma2
head(sigma2)
## [1] 299.7 304.1 249.4 212.9 177.3 212.6
head(1/phi)
## [1] 299.7602 304.1363 249.3766 212.9019 177.3364 212.5850
Se puede ver que los valores generados de \(\sigma^2\) son los mismos que uno partido por los valores generados de \(\phi\).
Vemos si el algoritmo ha convergido bien.
ts.plot(beta0)
ts.plot(cumsum(beta0)/c(1:length(beta0)))
acf(beta0)
Parece que sí
Es fácil ver las caracteristicas de las distribuciones a posteriori.
plot(density(beta0),xlab=expression(beta[0]),ylab='f',main='')
mean(beta0)
## [1] -18.05206
quantile(beta0,c(0.025,0.5,0.975))
## 2.5% 50% 97.5%
## -32.27075 -18.01500 -4.26745
También podemos hacer predicciones.
mediapred <- beta0+beta1*20
quantile(mediapred,c(0.025,0.5,0.975))
## 2.5% 50% 97.5%
## 55.38047 61.10000 67.12000
distpred <- mediapred+rnorm(length(sigma2),0,sqrt(sigma2))
quantile(distpred,c(0.025,0.5,0.975))
## 2.5% 50% 97.5%
## 30.16503 60.71175 93.87650
Los resultados son parecidos a los resultados clásicos.