5.9 Approssimazione di Laplace
Concludiamo questo capitolo discutendo un problema leggermente diverso da quello della sezione precedente, ma in un certo senso collegato: data una variabile \(X \in \R^d\) di cui sappiamo che la densità non è gaussiana, in quale senso è possibile comunque approssimarla con una gaussiana? In questo modo ad esempio gli strumenti sviluppati per le variabili gaussiane si potrebbero applicare, tenendo conto dell’errore di approssimazione, anche ad altre densità.
Una soluzione particolarmente semplice e spesso efficace è l’approssimazione di Laplace, che consiste nello sviluppare al secondo ordine il logaritmo della densità di \(X\) \[ x \mapsto \log( p(X=x)),\] (supponendo che \(X\) ammetta una densità continua e abbastanza regolare), in un punto di massimo \(x_{{\max}}\) (ossia una moda della densità di \(X\)). Poiché il gradiente si annulla, si trova lo sviluppo \[ \begin{split} & \log( p(X = x) ) \\ & = \log( p(X= x_{{\max}})) + \frac 12 (x-x_{{\max}}) \cdot H(x_{{\max}}) (x-x_{{\max}}) + O( |x-x_{{\max}}|^3), \end{split}\] dove \[ H(x) = \bra{ \frac{ \partial^2 \log (p(X=x))}{\partial x_i \partial x_j}}_{i,j=1}^d\] la matrice delle derivate seconde (detta anche hessiana). Essendo \(x_{{\max}}\) punto di massimo, \(H\) è una matrice (semi-)definita negativa. Supponendo che sia negativa, allora l’approssimazione di Laplace è data dalla densità gaussiana di valor medio \(x_{{\max}}\) e matrice delle covarianze \(- (H(x_{\max}))^{-1}\). L’utilità di questo metodo è che spesso, nel calcolare \(x_{{\max}}\) tramite opportuni metodi numerici si calcola anche la matrice hessiana (ad esempio con il metodo di Newton).
Va evidenziato tuttavia che non è garantita in generale che l’approssimazione sia vicina alla densità di \(X\), in particolare per valori \(x\) lontani da \(x_{{\max}}\). Vediamo degli esempi.
# Iniziamo con una densità non
# gaussiana ma piuttosto simile,
<- 0.01
deltax <- seq(0, 1, by = deltax)
x
<- x^4 * (1 - x)^4
densita <- densita/sum(densita * deltax)
densita
plot(x, densita, type = "l", lwd = 3, col = miei_colori[1],
ylab = "densità")
# calcoliamo il minimo dell'opposto del
# logaritmo della densità con la
# funzione nlm() -- questo si può anche
# fare a mano, ma poi lo possiamo
# applicare a casi generali. Dobbiamo
# comunque specificare la funzione
# fuori dall'intervallo [0,1],
# ponendola ad esempio infinita.
<- function(x) {
log_dens if (x < 0 | x > 1)
Inf else -log(x^4 * (1 - x)^4)
}
<- nlm(log_dens, p = 2/3, hessian = TRUE)
moda
# ricaviamo il punto di massimo e la
# matrice hessiana (qui la derivata
# seconda)
$estimate moda
## [1] 0.4999995
$hessian moda
## [,1]
## [1,] 32
# aggiungiamo ora al plot la densità
# ottenuta con l'approssimazione di
# Laplace
plot(x, densita, type = "l", lwd = 3, col = miei_colori[1],
ylab = "densità")
lines(x, dnorm(x, mean = moda$estimate, sd = sqrt(1/moda$hessian)),
lwd = 3, col = miei_colori[2])
legend("topright", legend = c("originale",
"approssimata"), fill = miei_colori[1:2])
Basta tuttavia modificare di poco l’esempio sopra per ottenere una cattiva approssimazione, dovuta all’asimmetria della densità.
<- x^3 * (1 - x)^5
densita <- densita/sum(densita * deltax)
densita
<- function(x) {
log_dens if (x < 0 | x > 1)
Inf else -log(x^3 * (1 - x)^5)
}
<- nlm(log_dens, p = 1/2, hessian = TRUE)
moda
plot(x, densita, type = "l", lwd = 3, col = miei_colori[1],
ylab = "densità")
lines(x, dnorm(x, mean = moda$estimate, sd = sqrt(1/moda$hessian)),
lwd = 3, col = miei_colori[2])
legend("topright", legend = c("originale",
"approssimata"), fill = miei_colori[1:2])
Nel caso di densità con più di un punto di massimo locale l’approssimazione è ben peggiore, come è naturale aspettarsi.
<- seq(-2, 2, by = deltax)
x <- exp(-(1 - x)^2 * (1 + x)^2)
densita <- densita/sum(densita * deltax)
densita
<- function(x) {
log_dens if (x < -2 | x > 2) {
Inf
else (1 - x)^2 * (1 + x)^2
}
}
<- nlm(log_dens, p = -1.5, hessian = TRUE)
moda
plot(x, densita, type = "l", lwd = 3, col = miei_colori[1],
ylim = c(0, 1.2), ylab = "densità")
lines(x, dnorm(x, mean = moda$estimate, sd = sqrt(1/moda$hessian)),
lwd = 3, col = miei_colori[2])
legend("topright", legend = c("originale",
"approssimata"), fill = miei_colori[1:2])
Consideriamo infine un esempio nel caso vettoriale. Approssimiamo variabile a valori in \(\R^2\) con densità \[ p( (X,Y ) = (x,y)) \propto (5-(y-\sin(2\pi x))^2 )(1-x^2)(1-y^2)\] per \(x\), \(y \in [-1,1]\) e nulla fuori.
<- 0.05
deltax <- 0.05
deltay
<- seq(-1, 1, by = deltax)
x <- seq(-1, 1, by = deltay)
y
<- length(x)
N_x <- length(y)
N_y
# creiamo una matrice con i valori
# della densità, inizialmente tutti
# nulli
<- matrix(nrow = N_x, ncol = N_y)
densita
# definiamo la funzione che calcola la
# densità
<- function(v) {
densita_funzione 5 - (v[2] - sin(2 * pi * v[1]))^2) *
(1 - v[1]^2) * (1 - v[2]^2)
(
}
for (i in 1:N_x) {
for (j in 1:N_y) {
<- densita_funzione(c(x[i],
densita[i, j]
y[j]))
}
}
<- densita/sum(densita * deltax *
densita
deltay)
filled.contour(x, y, densita, color.palette = viridis,
xlab = "x", ylab = "y")
Vediamone ora l’approssimazione di Laplace.
<- function(x) {
log_dens if (abs(x[1]) > 1 | abs(x[2]) > 1) {
Inf
else -log(densita_funzione(x))
}
}
<- nlm(log_dens, p = c(0.5, 0.5), hessian = TRUE)
moda
library(mvtnorm)
<- moda$estimate
m
# usiamo la funzione solve per
# calcolare l'inversa della matrice
# hessiana
<- solve(moda$hessian)
K
for (i in 1:N_x) {
for (j in 1:N_y) {
<- dmvt(c(x[i], y[j]),
densita[i, j]
m, K)
}
}
filled.contour(x, y, densita, color.palette = viridis,
xlab = "x", ylab = "y")
5.9.1 Esercizi
Esercizio 5.14 Scrivere l’approssimazione di Laplace per una densità proporzionale a \(x^3 (1-x)^2\) per \(x \in [0,1]\), e nulla altrimenti. Procedere sia analiticamente che tramite opportuni comandi R.