Lab 3 (cont)
Normale con media e varianza non note
library(dplyr) # optional
library(ggplot2)
theme_set(theme_minimal())
library(grid)
library(gridExtra)
library(tidyr)A priori non informativa
Distribuzione congiunta multivariata, distribuzione condizionale, distribuzione marginale, marginalizzazione e distribuzione predittiva a posteriori
Dati
y <- c(93, 112, 122, 135, 122, 150, 118, 90, 124, 114)Statistiche sufficienti
n <- length(y)
s2 <- var(y)
my <- mean(y)Fattorizziamo la congiunta a posteriori p(mu,sigma2|y) in p(sigma2|y)p(mu|sigma2,y) e campioniamo dalla congiunta a posteriori utilizzando questa fattorizzazione
# funzioni di supporto per campionare e valutare distribuzione chi-quadrato inversa
# scalata
rsinvchisq <- function(n, nu, s2, ...) nu * s2/rchisq(n, nu, ...)
dsinvchisq <- function(x, nu, s2) {
exp(log(nu/2) * nu/2 - lgamma(nu/2) + log(s2)/2 * nu - log(x) * (nu/2 + 1) - (nu *
s2/2)/x)
}Estraiamo 1000 valori casuali da p(sigma2|y)
ns <- 1000
sigma2 <- rsinvchisq(ns, n - 1, s2)Campioniamo da p(mu|sigma2,y)
mu <- my + sqrt(sigma2/n) * rnorm(ns)Campioniamo dalla distribuzione predittiva p(ynew|y) per ogni estrazione di (mu, sigma)
sigma <- sqrt(sigma2)
ynew <- rnorm(ns, mu, sigma)Per mu, sigma e ynew calcoliamo la densità su una griglia di valori
Ranges per la griglia
t1l <- c(90, 150)
t2l <- c(10, 60)
nl <- c(50, 185)
t1 <- seq(t1l[1], t1l[2], length.out = ns)
t2 <- seq(t2l[1], t2l[2], length.out = ns)
xynew <- seq(nl[1], nl[2], length.out = ns)Calcoliamo la densità marginale esatta di mu (pm)
# multiplication by 1/sqrt(s2/n) is due to the transformation of variable
# z=(x-mean(y))/sqrt(s2/n), see BDA3 p. 21
pm <- dt((t1 - my)/sqrt(s2/n), n - 1)/sqrt(s2/n)Stimiamo la densità marginale usando i campioni e un’approssimazione ad hoc con kernel Gaussiano (pmk)
pmk <- density(mu, adjust = 2, n = ns, from = t1l[1], to = t1l[2])$yFacciamo la stessa cosa per sigma (densità marginale esatta (ps)
# the multiplication by 2*t2 is due to the transformation of variable z=t2^2, see
# BDA3 p. 21
ps <- dsinvchisq(t2^2, n - 1, s2) * 2 * t2e approssimazione (psk))
psk <- density(sigma, n = ns, from = t2l[1], to = t2l[2])$yCalcoliamo la densità predittiva esatta (p_new)
# multiplication by 1/sqrt(s2/n) is due to the transformation of variable, see BDA3
# p. 21
p_new <- dt((xynew - my)/sqrt(s2 * (1 + 1/n)), n - 1)/sqrt(s2 * (1 + 1/n))Valutiamo la densità congiunta su una griglia (dfj$z).
Si noti che la densità che segue non è normalizzata, ma ciò è irrilevante quando si disegnano le curve di livello.
# Combine grid points into another data frame with all pairwise combinations
dfj <- data.frame(t1 = rep(t1, each = length(t2)), t2 = rep(t2, length(t1)))
dfj$z <- dsinvchisq(dfj$t2^2, n - 1, s2) * 2 * dfj$t2 * dnorm(dfj$t1, my, dfj$t2/sqrt(n))
# breaks for plotting the contours
cl <- seq(1e-05, max(dfj$z), length.out = 6)Visualizzazione delle densità congiunta e marginali
Visualizziamo la densità congiunta e le densità marginali della distribuzione a posteriori della normale con media e varianza non note.
Creiamo un grafico della densità marginale di mu
dfm <- data.frame(t1, Exact = pm, Empirical = pmk) %>%
gather(grp, p, -t1)
margmu <- ggplot(dfm) + geom_line(aes(t1, p, color = grp)) + coord_cartesian(xlim = t1l) +
labs(title = "Marginal of mu", x = "", y = "") + scale_y_continuous(breaks = NULL) +
theme(legend.background = element_blank(), legend.position = c(0.75, 0.8), legend.title = element_blank())Creiamo un grafico della densità marginale di sigma
dfs <- data.frame(t2, Exact = ps, Empirical = psk) %>%
gather(grp, p, -t2)
margsig <- ggplot(dfs) + geom_line(aes(t2, p, color = grp)) + coord_cartesian(xlim = t2l) +
coord_flip() + labs(title = "Marginal of sigma", x = "", y = "") + scale_y_continuous(breaks = NULL) +
theme(legend.background = element_blank(), legend.position = c(0.75, 0.8), legend.title = element_blank())
Coordinate system already present. Adding new coordinate system, which will replace the existing one.Creiamo un grafico della densità congiunta
joint1labs <- c("Samples", "Exact contour")
joint1 <- ggplot() + geom_point(data = data.frame(mu, sigma), aes(mu, sigma, col = "1"),
size = 0.1) + geom_contour(data = dfj, aes(t1, t2, z = z, col = "2"), breaks = cl) +
coord_cartesian(xlim = t1l, ylim = t2l) + labs(title = "Joint posterior", x = "",
y = "") + scale_y_continuous(labels = NULL) + scale_x_continuous(labels = NULL) +
scale_color_manual(values = c("blue", "black"), labels = joint1labs) + guides(color = guide_legend(nrow = 1,
override.aes = list(shape = c(16, NA), linetype = c(0, 1), size = c(2, 1)))) + theme(legend.background = element_blank(),
legend.position = c(0.5, 0.9), legend.title = element_blank())Combiniamo i grafici
# blank plot for combining the plots
bp <- grid.rect(gp = gpar(col = "white"), draw = F)
grid.arrange(joint1, margsig, margmu, bp, nrow = 2)Visualizzazione della distribuzione fattorizzata
Visualizziamo il campionamento fattorizzato e le corrispondenti densità marginali e condizionali.
Creiamo un’altro grafico della congiunta a posteriori
# data frame for the conditional of mu and marginal of sigma
dfc <- data.frame(mu = t1, marg = rep(sigma[1], length(t1)), cond = sigma[1] + dnorm(t1,
my, sqrt(sigma2[1]/n)) * 100) %>%
gather(grp, p, marg, cond)
# legend labels for the following plot
joint2labs <- c("Exact contour plot", "Sample from joint\n post.", "Cond. distribution\n of mu",
"Sample from the\n marg. of sigma")
joint2 <- ggplot() + geom_contour(data = dfj, aes(t1, t2, z = z, col = "1"), breaks = cl) +
geom_point(data = data.frame(m = mu[1], s = sigma[1]), aes(m, s, color = "2")) + geom_line(data = dfc,
aes(mu, p, color = grp), linetype = "dashed") + coord_cartesian(xlim = t1l, ylim = t2l) +
labs(title = "Joint posterior", x = "", y = "") + scale_x_continuous(labels = NULL) +
scale_color_manual(values = c("blue", "darkgreen", "darkgreen", "black"), labels = joint2labs) +
guides(color = guide_legend(nrow = 2, override.aes = list(shape = c(NA, 16, NA, NA),
linetype = c(1, 0, 1, 1)))) + theme(legend.background = element_blank(), legend.position = c(0.5,
0.85), legend.title = element_blank())Creiamo un’altro grafico della marginale di sigma
margsig2 <- ggplot(data = data.frame(t2, ps)) + geom_line(aes(t2, ps), color = "blue") +
coord_cartesian(xlim = t2l) + coord_flip() + labs(title = "Marginal of sigma", x = "",
y = "") + scale_y_continuous(labels = NULL)
Coordinate system already present. Adding new coordinate system, which will replace the existing one.e combiniamo i grafici
grid.arrange(joint2, margsig2, ncol = 2)Visualizzazione della distribuzione marginale di mu
Visualizziamo la distribuzione marginale di mu come una mistura di normali.
Calcoliamo le pdfs condizionali per ogni campione
condpdfs <- sapply(t1, function(x) dnorm(x, my, sqrt(sigma2/n)))
condpdfs %>%
dim
[1] 1000 1000Creiamo un grafico di alcune di esse
# data frame of 25 first samples
dfm25 <- data.frame(t1, t(condpdfs[1:25, ])) %>%
gather(grp, p, -t1)
condmu <- ggplot(data = dfm25) + geom_line(aes(t1, p, group = grp), linetype = "dashed") +
labs(title = "Conditional distribution of mu for first 25 samples", y = "", x = "") +
scale_y_continuous(breaks = NULL)Creiamo un grafico della loro media
dfsam <- data.frame(t1, colMeans(condpdfs), pm) %>%
gather(grp, p, -t1)
# labels
mulabs <- c("avg of sampled conds", "exact marginal of mu")
meanmu <- ggplot(data = dfsam) + geom_line(aes(t1, p, size = grp, color = grp)) + labs(y = "",
x = "mu") + scale_y_continuous(breaks = NULL) + scale_size_manual(values = c(2, 0.8),
labels = mulabs) + scale_color_manual(values = c("orange", "black"), labels = mulabs) +
theme(legend.position = c(0.8, 0.8), legend.background = element_blank(), legend.title = element_blank())Combiniamo i grafici
grid.arrange(condmu, meanmu, ncol = 1)Visualizzazione della distribuzione predittiva a posteriori
Visualizziamo il campionamento dalla distribuzione predittiva a posteriori.
Calcoliamo ogni pdf predittiva con mu e sigma dati
ynewdists <- sapply(xynew, function(x) dnorm(x, mu, sigma))
ynewdists %>%
dim
[1] 1000 1000Creiamo un grafico della congiunta a posteriori con un diagramma dalla distribuzione predittiva a posteriori, evidenziamo il primo campione, poi mostriamo tutti i campioni
# data frame of first draw from the sample of predictive pdfs along with the exact
# predictive pdf
dfp <- data.frame(xynew, draw = ynewdists[1, ], exact = p_new)
# data frame for plotting the ynew samples
dfy <- data.frame(ynew, p = 0.02 * max(ynewdists))
# legend labels
joint3labs <- c("Samples", "Exact contour")
pred1labs <- c("Sample from the predictive distribution", "Predictive distribution given the posterior sample")
pred2labs <- c("Samples from the predictive distribution", "Exact predictive distribution",
"Predictive distribution given the posterior sample")joint3 <- ggplot() + geom_point(data = data.frame(mu, sigma), aes(mu, sigma, col = "1"),
size = 0.1) + geom_contour(data = dfj, aes(t1, t2, z = z, col = "2"), breaks = cl) +
geom_point(data = data.frame(x = mu[1], y = sigma[1]), aes(x, y), color = "red") +
coord_cartesian(xlim = t1l, ylim = t2l) + labs(title = "Joint posterior", x = "mu",
y = "sigma") + scale_color_manual(values = c("blue", "black"), labels = joint3labs) +
guides(color = guide_legend(nrow = 1, override.aes = list(shape = c(16, NA), linetype = c(0,
1), size = c(2, 1)))) + theme(legend.background = element_blank(), legend.position = c(0.5,
0.9), legend.title = element_blank())Creiamo un grafico della prima distribuzione predittiva campionata ed il rispettivo campione ynew
pred1 <- ggplot() + geom_line(data = dfp, aes(xynew, draw, color = "2")) + geom_point(data = dfy,
aes(ynew[1], p, color = "1")) + coord_cartesian(xlim = nl, ylim = c(0, 0.04)) + labs(title = "Posterior predictive distribution",
x = "ytilde", y = "") + scale_y_continuous(breaks = NULL) + scale_color_manual(values = c("red",
"blue"), labels = pred1labs) + guides(color = guide_legend(nrow = 2, override.aes = list(linetype = c(0,
1), shape = c(16, NA), labels = pred1labs))) + theme(legend.background = element_blank(),
legend.position = c(0.5, 0.9), legend.title = element_blank())Creiamo un grafico con tutti gli ynews
pred2 <- ggplot() + geom_line(data = dfp, aes(xynew, draw, color = "3"), alpha = 0.5) +
geom_line(data = dfp, aes(xynew, exact, color = "2")) + geom_point(data = dfy, aes(ynew,
p, color = "1"), alpha = 0.05) + coord_cartesian(xlim = nl, ylim = c(0, 0.04)) + labs(x = "ytilde",
y = "") + scale_y_continuous(breaks = NULL) + scale_color_manual(values = c("red",
"black", "blue"), labels = pred2labs) + guides(color = guide_legend(nrow = 3, override.aes = list(linetype = c(0,
1, 1), shape = c(16, NA, NA), alpha = c(1, 1, 0.5), labels = pred2labs))) + theme(legend.background = element_blank(),
legend.position = c(0.5, 0.9), legend.title = element_blank())Combiniamo i grafici
grid.arrange(joint3, pred1, bp, pred2, nrow = 2)