Considere los siguientes modelos para realizar tareas de agrupamiento de observaciones multivariadas \(\boldsymbol{y}_1,\ldots,\boldsymbol{y}_n\) con \(\boldsymbol{y}_i = (y_{i,1},\ldots,y_{i,p})\) para \(i=1,\ldots,n\) y \(p\geq 2\).
Distribución muestral: \[ \boldsymbol{y}_i\mid\xi_i,\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma}\stackrel{\text {ind}}{\sim}\small{\textsf{N}}(\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma})\,,\qquad i=1,\ldots,n\,, \] donde \(\xi_i\) es una variable categórica que asume valores en el conjunto de enteros positivos \(\{1,\ldots,H\}\) con pro-ba-bi-li-da-des \(\textsf{Pr}(\xi_i = h\mid\omega_h) = \omega_h\) para \(i=1,\ldots,n\) y \(h=1,\ldots,H\), tales que \(0<\omega_h<1\) y \(\sum_{h=1}^H \omega_h = 1\), \(\boldsymbol{\theta}_h\) es el vector de medias específico del grupo \(h\) para \(h=1,\ldots,H\), y \(\mathbf{\Sigma}\) es la matriz de covarianza común a todos los grupos.
Distribución previa: \[ p(\boldsymbol{\xi},\boldsymbol{\omega},\boldsymbol{\theta},\mathbf{\Sigma}) = p(\boldsymbol{\xi}\mid\boldsymbol{\omega})\,p(\boldsymbol{\omega})\,p(\boldsymbol{\theta})\,p(\mathbf{\Sigma}) \] donde \(\boldsymbol{\xi}=(\xi_1,\ldots,\xi_n)\), \(\boldsymbol{\omega}=(\omega_1,\ldots,\omega_H)\), y \(\boldsymbol{\theta}= (\boldsymbol{\theta}_1,\ldots,\boldsymbol{\theta}_H)\) con \[ \begin{align*} \boldsymbol{\xi}\mid \boldsymbol{\omega}&\sim \small{\textsf{Categorica}}(\boldsymbol{\omega}) \\ \boldsymbol{\omega}&\sim \small{\textsf{Dirichlet}}(\boldsymbol{\alpha}_0)\\ \boldsymbol{\theta}_h &\stackrel{\text {iid}}{\sim}\small{\textsf{N}}(\boldsymbol{\mu}_0,\mathbf{\Lambda}_0) \\ \mathbf{\Sigma}&\sim \small{\textsf{WI}}\left(\nu_0,\mathbf{S}_0^{-1}\right) \end{align*} \] y \(\boldsymbol{\alpha}_0\), \(\boldsymbol{\mu}_0\), \(\mathbf{\Lambda}_0\), \(\nu_0\), \(\mathbf{S}_0\) son hiperparámetros.
Distribución muestral: \[ \boldsymbol{y}_i\mid\xi_i,\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma}_{\xi_i} \stackrel{\text {ind}}{\sim}\small{\textsf{N}}(\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma}_{\xi_i})\,,\qquad i=1,\ldots,n\,, \] donde \(\xi_i\) es una variable categórica que asume valores en el conjunto de enteros positivos \(\{1,\ldots,H\}\) con pro-ba-bi-li-da-des \(\textsf{Pr}(\xi_i = h\mid\omega_h) = \omega_h\) para \(i=1,\ldots,n\) y \(h=1,\ldots,H\), tales que \(0<\omega_h<1\) y \(\sum_{h=1}^H \omega_h = 1\), \(\boldsymbol{\theta}_h\) y \(\mathbf{\Sigma}_{h}\) son el vector de medias y la matriz de covarianza específicos del grupo \(h\) para \(h=1,\ldots,H\), respectivamente.
Distribución previa: \[ p(\boldsymbol{\xi},\boldsymbol{\omega},\boldsymbol{\theta},\mathbf{\Sigma}) = p(\boldsymbol{\xi}\mid\boldsymbol{\omega})\,p(\boldsymbol{\omega})\,p(\boldsymbol{\theta})\,p(\mathbf{\Sigma}) \] donde \(\boldsymbol{\xi}=(\xi_1,\ldots,\xi_n)\), \(\boldsymbol{\omega}=(\omega_1,\ldots,\omega_H)\), \(\boldsymbol{\theta}= (\boldsymbol{\theta}_1,\ldots,\boldsymbol{\theta}_H)\), y \(\mathbf{\Sigma}= (\mathbf{\Sigma}_1,\ldots,\mathbf{\Sigma}_H)\) con \[ \begin{align*} \boldsymbol{\xi}\mid \boldsymbol{\omega}&\sim \small{\textsf{Categorica}}(\boldsymbol{\omega}) \\ \boldsymbol{\omega}&\sim \small{\textsf{Dirichlet}}(\boldsymbol{\alpha}_0)\\ \boldsymbol{\theta}_h &\stackrel{\text {iid}}{\sim}\small{\textsf{N}}(\boldsymbol{\mu}_0,\mathbf{\Lambda}_0) \\ \mathbf{\Sigma}_h &\stackrel{\text {iid}}{\sim}\small{\textsf{WI}}\left(\nu_0,\mathbf{S}_0^{-1}\right) \end{align*} \] y \(\boldsymbol{\alpha}_0\), \(\boldsymbol{\mu}_0\), \(\mathbf{\Lambda}_0\), \(\nu_0\), \(\mathbf{S}_0\) son hiperparámetros.
Las bases de datos \(\textsf{D}_1,\textsf{D}_2,\textsf{D}_3,\textsf{D}_4,\textsf{D}_5,\textsf{D}_6\)
corresponden a seis (6) conjuntos de datos sintéticos con diferentes
características para probar las bondades de agrupamiento de \(\textsf{M}_1\) y \(\textsf{M}_2\). Estos datos están
inspirados en el artículo Clustering benchmark datasets exploiting
the fundamental clustering problems (https://www.sciencedirect.com/science/article/pii/S2352340920303954),
donde se presenta una colección de conjuntos de datos de fácil acceso en
R
para comparar varios métodos de agrupamiento.
Los datos se encuentran disponibles en Moodle por medio de archivos que contienen dos objetos:
Y
: matriz de datos de tamaño \(n\times p\) que contiene las observaciones
\(p\)-variadas \(\boldsymbol{y}_1,\ldots,\boldsymbol{y}_n\)
por filas.xi
: concatenación de tamaño \(n\) que contiene la partición de los datos
verdadera \(\xi_1,\ldots,\xi_n\) con la
que se generaron los datos.Se observa que la partición dada en xi
sirve para
reconocer la número de grupos verdadero \(H\), así como punto de referencia para
evaluar la calidad de la segmentación inferida por medio de los modelos
bajo consideración.
Hacer una visualización de cada \(\textsf{D}_k\), para \(k=1,\ldots,6\), usando una convención de colores y/o símbolos adecuada que permita identificar fácilmente los grupos verdaderos. Presentar todas las visualizaciones en un solo panel de \(2\times3\) o \(3\times2\) para reconocer las características propias de cada conjunto de datos.
rango <- c(-1,1)*6
col <- RColorBrewer::brewer.pal(n = 9, name = "Set1")
pch <- c(16,15,17,18)
par(mfrow = c(2,3), mar = c(2.75,2.75,1.5,0.5), mgp = c(1.7,0.7,0))
for (j in 1:6) {
load(paste0("D",j,".RData"))
plot(Y, col = adjustcolor(col[xi], 0.5), pch = pch[xi], xlim = rango, ylim = rango, xlab = expression(y[1]), ylab = expression(y[2]), main = paste0("D",j))
abline(h = 0, v = 0, col = "lightgray")
}
Representar cada modelo por medio de un DAG. Presentar los dos esquemas en un solo panel de \(2\times1\) para reconocer las características propias de cada modelo.
Bajo \(\textsf{M}_1\), demostrar las distribuciones condicionales completas de \(\boldsymbol{\theta}_h\), \(\mathbf{\Sigma}\), \(\xi_i\), y \(\boldsymbol{\omega}\).
La distribución condicional completa de \(\boldsymbol{\theta}_h\), para \(h = 1,\ldots,H\), es \(\boldsymbol{\theta}_h\mid\text{resto}\sim\small{\textsf{N}}(\boldsymbol{\mu}_n,\mathbf{\Lambda}_n)\) con: \[ \boldsymbol{\mu}_n = \left( \mathbf{\Lambda}_0^{-1} + n_h\mathbf{\Sigma}^{-1} \right)^{-1} \left( \mathbf{\Lambda}_0^{-1}\boldsymbol{\mu}_0 + n_h\mathbf{\Sigma}^{-1}\bar{\boldsymbol{y}}_h \right) \qquad\text{y}\qquad \mathbf{\Lambda}_n = \left( \mathbf{\Lambda}_0^{-1} + n_h\mathbf{\Sigma}^{-1} \right)^{-1} \] donde \(n_h = |\{i:\xi_i=h\}|\) es el número de individuos del grupo \(h\) y \[ \bar{\boldsymbol{y}}_h = \frac{1}{n_h}\sum_{i:\xi_i=h}\boldsymbol{y}_i \] es la media de las observaciones del grupo \(h\). Finalmente, si \(n_h = 0\), entonces \(\boldsymbol{\mu}_n = \boldsymbol{\mu}_0\) y \(\mathbf{\Lambda}_n = \mathbf{\Lambda}_0\).
sample_Theta_M1 <- function (H, nh, Ybh, L0, m0, iL0, iLm0, Theta, Sigma)
{
# Theta: H x p
for (h in 1:H) {
if (nh[h] > 0) {
iS <- solve(Sigma)
Vh <- solve(iL0 + nh[h]*iS)
Theta[h,] <- c(mvtnorm::rmvnorm(1, Vh%*%(iLm0 + nh[h]*(iS%*%Ybh[h,])), Vh))
} else {
Theta[h,] <- c(mvtnorm::rmvnorm(1, m0, L0))
}
}
return(Theta)
}
La distribución condicional completa de \(\mathbf{\Sigma}\) es \(\mathbf{\Sigma}\mid\text{resto}\sim\textsf{WI}(\nu_n,\mathbf{S}_n^{-1})\) con: \[ \nu_n = \nu_0 + n \qquad\text{y}\qquad \mathbf{S}_n = \mathbf{S}_0 + \sum_{i=1}^n(\boldsymbol{y}_i - \boldsymbol{\theta}_{\xi_i})(\boldsymbol{y}_i - \boldsymbol{\theta}_{\xi_i})^{\textsf{T}}\,. \]
sample_Sigma_M1 <- function(H, nh, Ybh, Sh, nun, S0, Theta)
{
# Sigma: p x p
tmp <- 0
for(h in 1:H) {
if (nh[h] > 0) {
if (nh[h] == 1) {
tmp <- tmp + S0 + ((Ybh[h,] - Theta[h,])%*%t(Ybh[h,] - Theta[h,]))
} else {
tmp <- tmp + (nh[h]-1)*Sh[,,h] + nh[h]*((Ybh[h,] - Theta[h,])%*%t(Ybh[h,] - Theta[h,]))
}
}
}
return(solve(rWishart::rWishart(1, nun, solve(S0 + tmp))[,,1]))
}
La distribución condicional completa de \(\xi_i\), para \(i=1,\ldots,n\), es una distribución de probabilidad discreta tal que: \[ p(\xi_i = h\mid\text{resto})\propto \omega_h\, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_h,\mathbf{\Sigma}) \] y por lo tanto \[ \textsf{Pr}(\xi_i = h\mid\text{resto}) = \frac{ \omega_h\, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_h,\mathbf{\Sigma}) }{ \sum_{h=1}^H \omega_h, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_{h},\mathbf{\Sigma}) } \] para \(h = 1,\ldots,H\).
sample_xi_M1 <- function (n, H, xi, omega, Theta, Sigma, Y)
{
# xi: n
for (i in 1:n) {
lp <- NULL
for (h in 1:H) {
lp[h] <- log(omega[h]) + mvtnorm::dmvnorm(Y[i,], Theta[h,], Sigma, log = T)
}
xi[i] <- sample(x = 1:H, size = 1, replace = F, prob = exp(lp - max(lp)))
}
return(xi)
}
La distribución condicional completa de \(\boldsymbol{\omega}\) es: \[ \boldsymbol{\omega}\mid\text{resto} \sim \small{\textsf{Dirichlet}}(\alpha^0_1+n_1,\ldots,\alpha^0_{H}+n_H)\,. \]
sample_omega_M1 <- function (nh, al0)
{
# omega: H
return(c(gtools::rdirichlet(1, al0 + nh)))
}
La log-verosimilitud de \(\textsf{M}_1\) es:
\[ \ell = \sum_{i=1}^n\log (\boldsymbol{y}_i\mid\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma})\,. \]
ll_M1 <- function(Y, Theta, Sigma, xi)
{
# escalar
out <- 0
for (i in 1:nrow(Y))
out <- out + mvtnorm::dmvnorm(Y[i,], Theta[xi[i],], Sigma, T)
return(out)
}
Bajo \(\textsf{M}_2\), demostrar las distribuciones condicionales completas de \(\boldsymbol{\theta}_h\), \(\mathbf{\Sigma}_h\), \(\xi_i\), y \(\boldsymbol{\omega}\).
La distribución condicional completa de \(\boldsymbol{\theta}_h\), para \(h = 1,\ldots,H\), es \(\boldsymbol{\theta}_h\mid\text{resto}\sim\small{\textsf{N}}(\boldsymbol{\mu}_n,\mathbf{\Lambda}_n)\) con: \[ \boldsymbol{\mu}_n = \left( \mathbf{\Lambda}_0^{-1} + n_h\mathbf{\Sigma}_h^{-1} \right)^{-1} \left( \mathbf{\Lambda}_0^{-1}\boldsymbol{\mu}_0 + n_h\mathbf{\Sigma}_h^{-1}\bar{\boldsymbol{y}}_h \right) \qquad\text{y}\qquad \mathbf{\Lambda}_n = \left( \mathbf{\Lambda}_0^{-1} + n_h\mathbf{\Sigma}_h^{-1} \right)^{-1} \] donde \(n_h = |\{i:\xi_i=h\}|\) es el número de individuos del grupo \(h\) y \[ \bar{\boldsymbol{y}}_h = \frac{1}{n_h}\sum_{i:\xi_i=h}\boldsymbol{y}_i \] es la media de las observaciones del grupo \(h\). Finalmente, si \(n_h = 0\), entonces \(\boldsymbol{\mu}_n = \boldsymbol{\mu}_0\) y \(\mathbf{\Lambda}_n = \mathbf{\Lambda}_0\).
sample_Theta_M2 <- function (H, nh, Ybh, L0, m0, iL0, iLm0, Theta, Sigma)
{
# Theta: H x p
for (h in 1:H) {
if (nh[h] > 0) {
iS <- solve(Sigma[,,h])
Vh <- solve(iL0 + nh[h]*iS)
Theta[h,] <- c(mvtnorm::rmvnorm(1, Vh%*%(iLm0 + nh[h]*(iS%*%Ybh[h,])), Vh))
} else {
Theta[h,] <- c(mvtnorm::rmvnorm(1, m0, L0))
}
}
return(Theta)
}
La distribución condicional completa de \(\mathbf{\Sigma}_h\) es \(\mathbf{\Sigma}_h\mid\text{resto}\sim\textsf{WI}(\nu_n,\mathbf{S}_n^{-1})\) con: \[ \nu_n = \nu_0 + n_h \qquad\text{y}\qquad \mathbf{S}_n = \mathbf{S}_0 + \sum_{i:\xi_i=h}(\boldsymbol{y}_i - \boldsymbol{\theta}_{h})(\boldsymbol{y}_i - \boldsymbol{\theta}_{h})^{\textsf{T}}\,. \]
sample_Sigma_M2 <- function(H, nh, Ybh, Sh, nu0, S0, iS0, Theta, Sigma)
{
# Sigma: p x p x H
for(h in 1:H) {
if (nh[h] > 0) {
if (nh[h] == 1) {
Sigma[,,h] <- solve(rWishart::rWishart(1, nu0 + 1, solve(S0 + ((Ybh[h,] - Theta[h,])%*%t(Ybh[h,] - Theta[h,]))))[,,1])
} else {
Sigma[,,h] <- solve(rWishart::rWishart(1, nu0 + nh[h], solve(S0 + (nh[h]-1)*Sh[,,h] + nh[h]*((Ybh[h,] - Theta[h,])%*%t(Ybh[h,] - Theta[h,]))))[,,1])
}
} else {
Sigma[,,h] <- solve(rWishart::rWishart(1, nu0, iS0)[,,1])
}
}
return(Sigma)
}
La distribución condicional completa de \(\xi_i\), para \(i=1,\ldots,n\), es una distribución de probabilidad discreta tal que: \[ p(\xi_i = h\mid\text{resto})\propto \omega_h\, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_h,\mathbf{\Sigma}_h) \] y por lo tanto \[ \textsf{Pr}(\xi_i = h\mid\text{resto}) = \frac{ \omega_h\, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_h,\mathbf{\Sigma}_h) }{ \sum_{h=1}^H \omega_h, \small{\textsf{N}}(\boldsymbol{y}_i\mid\boldsymbol{\theta}_{h},\mathbf{\Sigma}_h) } \] para \(h = 1,\ldots,H\).
sample_xi_M2 <- function (n, H, xi, omega, Theta, Sigma, Y)
{
# xi: n
for (i in 1:n) {
lp <- NULL
for (h in 1:H) {
lp[h] <- log(omega[h]) + mvtnorm::dmvnorm(Y[i,], Theta[h,], Sigma[,,h], log = T)
}
xi[i] <- sample(x = 1:H, size = 1, replace = F, prob = exp(lp - max(lp)))
}
return(xi)
}
La distribución condicional completa de \(\boldsymbol{\omega}\) es: \[ \boldsymbol{\omega}\mid\text{resto} \sim \small{\textsf{Dirichlet}}(\alpha^0_1+n_1,\ldots,\alpha^0_{H}+n_H)\,. \]
sample_omega_M2 <- function (nh, al0)
{
# omega: H
c(gtools::rdirichlet(1, al0 + nh))
}
La log-verosimilitud de \(\textsf{M}_2\) es:
\[ \ell = \sum_{i=1}^n\log (\boldsymbol{y}_i\mid\boldsymbol{\theta}_{\xi_i},\mathbf{\Sigma}_{\xi_i})\,. \]
ll_M2 <- function(Y, Theta, Sigma, xi)
{
# escalar
out <- 0
for (i in 1:nrow(Y))
out <- out + mvtnorm::dmvnorm(Y[i,], Theta[xi[i],], Sigma[,,xi[i]], T)
return(out)
}
Ajustar cada uno de los modelos por medio de un muestreador de Gibbs con 1000 iteraciones de calentamiento y 1000 iteraciones efectivas espaciadas cada 10 iteraciones (para un total de 10000 iteraciones) usando el valor de \(H\) dado en la partición de referencia y los hiperparámetros \(\boldsymbol{\alpha}_0=(1/H,\ldots,1/H)\), \(\boldsymbol{\mu}_0=\frac{1}{n}\sum_{i=1}^n \boldsymbol{y}_i\), \(\mathbf{\Lambda}_0=\frac{1}{n-1}\sum_{i=1}^n (\boldsymbol{y}_i-\bar{\boldsymbol{y}})(\boldsymbol{y}_i-\bar{\boldsymbol{y}})^{\textsf{T}}\), \(\nu_0 = p+2\), y \(\mathbf{S}_0 = \mathbf{\Lambda}_0\).
Con el fin de inicializar el algoritmo de manera conveniente para que la cadena sea estacionaria rápidamente, implementar el método de agrupamiento de \(K\)-medias con \(H\) grupos, y fijar \(\boldsymbol{\xi}^{(0)}\) a la partición resultante, \(\boldsymbol{\omega}^{(0)}\) a las frecuencias relativas de los grupos, \(\boldsymbol{\theta}^{(0)}\) a los centros de los grupos, y \(\mathbf{\Sigma}^{(0)}\) al promedio de las matrices de covarianza de los grupos en el caso de \(\textsf{M}_1\) y a las matrices de covarianza de los grupos en el caso de \(\textsf{M}_2\).
Para cada combinación de modelo y conjunto de datos, calcular la media posterior el Índice de Rand Ajustado (ARI, por sus siglas en inglés) junto con el Criterio de Información de Watanabe-Akaike (WAIC, por sus siglas en inglés). Presentar todos los resultados organizadamente en una sola tabla para facilitar la interpretación de los resultados.
# muestreador de Gibbs para ajustar M1
MCMC_M1 <- function (niter, nburn, nskip, Y, H, xi0, verbose = TRUE)
{
# numero iteraciones
B <- nburn + nskip*niter
ncat <- floor(0.1*B)
# hiperparametros
n <- nrow(Y)
p <- ncol(Y)
m0 <- colMeans(Y)
L0 <- cov(Y)
nu0 <- p+2
S0 <- L0
al0 <- rep(1/H, H)
# cantidades y valores iniciales
iL0 <- solve(L0)
iLm0 <- solve(L0)%*%m0
nun <- nu0 + n
set.seed(1)
km <- stats::kmeans(x = Y, centers = H)
xi <- c(km$cluster)
omega <- as.numeric(table(factor(xi, levels = 1:H))/n)
Theta <- km$centers
# almacenamiento
THETA <- SIGMA <- OMEGA <- XI <- LP <- ARI <- NULL
# cadena
set.seed(1)
for (b in 1:B) {
# actualizar estadisticos
nh <- as.numeric(table(factor(xi, levels = 1:H)))
Ybh <- array(NA, c(H, p))
Sh <- array(NA, c(p, p, H))
for (h in 1:H) {
if (nh[h] > 0) {
index_h <- xi == h
if (nh[h] == 1) {
Ybh[h,] <- Y[index_h,]
} else {
Ybh[h,] <- colMeans(Y[index_h,])
Sh[,,h] <- cov(Y[index_h,])
}
}
}
# actualizar parametros
Sigma <- sample_Sigma_M1(H, nh, Ybh, Sh, nun, S0, Theta)
Theta <- sample_Theta_M1(H, nh, Ybh, L0, m0, iL0, iLm0, Theta, Sigma)
xi <- sample_xi_M1 (n, H, xi, omega, Theta, Sigma, Y)
omega <- sample_omega_M1(nh, al0)
# almacenar y log-verosimilitud
if (b > nburn) {
if (b%%nskip == 0) {
XI <- rbind(XI, c(xi))
THETA <- rbind(THETA, c(Theta))
SIGMA <- rbind(SIGMA, c(Sigma))
OMEGA <- rbind(OMEGA, c(omega))
LP <- rbind(LP, c(ll_M1(Y, Theta, Sigma, xi)))
ARI <- rbind(ARI, c(aricode::RI (xi, xi0)))
}
}
# progreso
if (verbose) if (b%%ncat == 0) cat(100*round(b/B, 1), "% completado \n", sep = "")
}
# return
return(list(XI = XI, THETA = THETA, SIGMA = SIGMA, OMEGA = OMEGA, LP = LP, ARI = ARI))
}
EL WAIC se calcula como: \[ \text{WAIC} = -2\text{lppd} + 2p_{\text{WAIC}} \] donde \[ \begin{align*} \text{lppd} &= \text{log}\prod_{i=1}^n p(\boldsymbol{y}_i\mid\mathbf{Y})\\ &\approx \sum_{i=1}^n\text{log}\left(\frac{1}{B}\sum_{b=1}^B p\left(\boldsymbol{y}_i\mid\boldsymbol{\theta}^{(b)}\right)\right) \end{align*} \] es la log densidad predictiva puntual (que como la devianza resume la precisión predictiva del modelo ajustado a los datos), y \[ \begin{align*} p_{\text{WAIC}} &= 2\sum_{i=1}^n\left( \text{log}\,\textsf{E}(p(\boldsymbol{y}_i\mid\boldsymbol{\theta})\mid\mathbf{Y}) - \textsf{E}(\text{log}\,p(\boldsymbol{y}_i\mid\boldsymbol{\theta})\mid\mathbf{Y}) \right)\\ &\approx 2\sum_{i=1}^n\left(\text{log}\left( \frac{1}{B}\sum_{b=1}^B p\left(\boldsymbol{y}_i\mid\boldsymbol{\theta}^{(b)}\right) \right) - \frac{1}{B}\sum_{b=1}^B \text{log}\,p\left(\boldsymbol{y}_i\mid \boldsymbol{\theta}^{(b)} \right)\right) \end{align*} \] es el número efectivo de parámetros.
WAIC_M1 <- function (Y, muestras)
{
B <- nrow(muestras$XI)
n <- nrow(Y)
p <- ncol(Y)
lppd <- pWAIC <- 0
for (i in 1:n) {
tmp1 <- tmp2 <- 0
for (b in 1:B) {
xi <- muestras$XI[b,]
Theta <- matrix(data = muestras$THETA[b,], nrow = H, ncol = p)
Sigma <- matrix(data = muestras$SIGMA[b,], nrow = p, ncol = p)
aux <- mvtnorm::dmvnorm(x = Y[i,], mean = Theta[xi[i],], sigma = Sigma, log = T)
tmp1 <- tmp1 + exp(aux)/B
tmp2 <- tmp2 + aux/B
}
lppd <- lppd + log(tmp1)
pWAIC <- pWAIC + 2*(log(tmp1) - tmp2)
}
# return
-2*lppd + 2*pWAIC
}
# muestreador de Gibbs para ajustar M2
MCMC_M2 <- function (niter, nburn, nskip, Y, H, xi0, verbose = TRUE)
{
# numero iteraciones
B <- nburn + nskip*niter
ncat <- floor(0.1*B)
# hiperparametros
n <- nrow(Y)
p <- ncol(Y)
m0 <- colMeans(Y)
L0 <- cov(Y)
nu0 <- p+2
S0 <- L0
al0 <- rep(1/H, H)
iL0 <- solve(L0)
iLm0 <- solve(L0)%*%m0
iS0 <- solve(S0)
# valores iniciales
set.seed(1)
km <- stats::kmeans(x = Y, centers = H)
xi <- c(km$cluster)
omega <- as.numeric(table(factor(xi, levels = 1:H))/n)
Theta <- km$centers
Sigma <- array(data = NA, dim = c(p,p,H))
for (h in 1:H)
Sigma[,,h] <- cov(Y[xi == h,])
# almacenamiento
THETA <- SIGMA <- OMEGA <- XI <- LP <- ARI <- NULL
# cadena
set.seed(1)
for (b in 1:B) {
# actualizar estadisticos
nh <- as.numeric(table(factor(xi, levels = 1:H)))
Ybh <- array(NA, c(H, p))
Sh <- array(NA, c(p, p, H))
for (h in 1:H) {
if (nh[h] > 0) {
index_h <- xi == h
if (nh[h] == 1) {
Ybh[h,] <- Y[index_h,]
} else {
Ybh[h,] <- colMeans(Y[index_h,])
Sh[,,h] <- cov(Y[index_h,])
}
}
}
# actualizar parametros
Sigma <- sample_Sigma_M2(H, nh, Ybh, Sh, nu0, S0, iS0, Theta, Sigma)
Theta <- sample_Theta_M2(H, nh, Ybh, L0, m0, iL0, iLm0, Theta, Sigma)
xi <- sample_xi_M2 (n, H, xi, omega, Theta, Sigma, Y)
omega <- sample_omega_M2(nh, al0)
# almacenar y log-verosimilitud
if (b > nburn) {
if (b%%nskip == 0) {
XI <- rbind(XI, c(xi))
THETA <- rbind(THETA, c(Theta))
SIGMA <- rbind(SIGMA, c(Sigma))
OMEGA <- rbind(OMEGA, c(omega))
LP <- rbind(LP, ll_M2(Y, Theta, Sigma, xi))
ARI <- rbind(ARI, c(aricode::RI (xi, xi0)))
}
}
# progreso
if (verbose) if (b%%ncat == 0) cat(100*round(b/B, 1), "% completado \n", sep = "")
}
# return
return(list(XI = XI, THETA = THETA, SIGMA = SIGMA, OMEGA = OMEGA, LP = LP, ARI = ARI))
}
WAIC_M2 <- function (Y, muestras)
{
B <- nrow(muestras$XI)
n <- nrow(Y)
p <- ncol(Y)
lppd <- pWAIC <- 0
for (i in 1:n) {
tmp1 <- tmp2 <- 0
for (b in 1:B) {
xi <- muestras$XI[b,]
Theta <- array(data = muestras$THETA[b,], dim = c(H,p))
Sigma <- array(data = muestras$SIGMA[b,], dim = c(p,p,H))
aux <- mvtnorm::dmvnorm(x = Y[i,], mean = Theta[xi[i],], sigma = Sigma[,,xi[i]], log = T)
tmp1 <- tmp1 + exp(aux)/B
tmp2 <- tmp2 + aux/B
}
lppd <- lppd + log(tmp1)
pWAIC <- pWAIC + 2*(log(tmp1) - tmp2)
}
# return
-2*lppd + 2*pWAIC
}
# iteraciones
niter <- 1000
nburn <- 1000
nskip <- 10
# ajuste
for (j in 1:6) {
# datos
load(file = paste0("D",j,".RData"))
H <- max(xi)
for (k in 1:2) {
nombre <- paste0("muestras","_",j,"_","M",k)
mcmc <- get(x = paste0("MCMC_M",k))
waic <- get(x = paste0("WAIC_M",k))
assign(x = nombre, value = mcmc(niter, nburn, nskip, Y, H, xi, verbose = FALSE))
muestras <- get(x = nombre)
criterio <- waic(Y, muestras)
save(muestras, criterio, file = paste0(nombre,".RData"))
}
}
tab <- NULL
for (j in 1:6) {
tmp <- NULL
for (k in 1:2) {
load(file = paste0("muestras","_",j,"_","M",k,".RData"))
tmp <- c(tmp, mean(muestras$ARI), criterio)
}
tab <- rbind(tab, tmp)
}
colnames(tab) <- c("M1 : ARI", "M1 : WAIC", "M2 : ARI", "M2 : WAIC")
rownames(tab) <- c(paste0("D",1:6))
knitr::kable(x = tab, digits = c(3,1), align = "c")
M1 : ARI | M1 : WAIC | M2 : ARI | M2 : WAIC | |
---|---|---|---|---|
D1 | 0.914 | 929.1 | 0.904 | 936.9 |
D2 | 0.922 | 918.1 | 0.942 | 847.4 |
D3 | 0.898 | 635.3 | 0.940 | 588.0 |
D4 | 0.912 | 526.7 | 0.966 | 481.3 |
D5 | 0.828 | 1303.6 | 0.844 | 1271.4 |
D6 | 0.981 | 478.2 | 0.978 | 484.1 |
Bajo \(\textsf{M}_1\), hacer un diagrama de calor de cada matriz de incidencia a posteriori ordenada de acuerdo con la partición de referencia. Presentar todas las visualizaciones en un solo panel de \(2\times3\) o \(3\times2\) para reconocer las características propias de cada matriz de incidencia.
get_incidence_matrix <- function(XI)
{
# matriz de incidencia
n <- ncol(XI)
B <- nrow(XI)
A <- matrix(data = 0, nrow = n, ncol = n)
for (b in 1:B) {
for (i in 1:(n-1)) {
for (j in (i+1):n) {
if (XI[b,i] == XI[b,j]) {
A[i,j] <- A[i,j] + 1/B
}
}
}
}
A <- A + t(A)
diag(A) <- 1
return(A)
}
heat.plot0 <- function (mat, show.grid = FALSE, cex.axis, tick, labs, col.axis,...)
{
# funcion para graficar las probabilidades por medio de un diagrama de calor
JJ <- dim(mat)[1]
colorscale <- c("white", rev(heat.colors(100)))
if(missing(labs)) labs <- 1:JJ
if(missing(col.axis)) col.axis <- rep("black", JJ)
if(missing(cex.axis)) cex.axis <- 0.5
if(missing(tick)) tick <- TRUE
## adjacency matrix
image(seq(1, JJ), seq(1, JJ), mat, axes = FALSE, xlab = "", ylab = "",
col = colorscale[seq(floor(100*min(mat)), floor(100*max(mat)))], ...)
for(j in 1:JJ){
axis(1, at = j, labels = labs[j], las = 2, cex.axis = cex.axis, tick, col.axis = col.axis[j])
axis(2, at = j, labels = labs[j], las = 2, cex.axis = cex.axis, tick, col.axis = col.axis[j])
}
box()
if(show.grid) grid(nx = JJ, ny = JJ)
}
par(mfrow = c(2,3), mar = c(2.75,2.75,1.5,0.5), mgp = c(1.7,0.7,0))
for (j in 1:6) {
load(file = paste0("muestras","_",j,"_","M1.RData"))
A <- get_incidence_matrix(muestras$XI)
heat.plot0(mat = A, labs = NA, tick = F, main = paste("M1 : D",j))
}
Bajo \(\textsf{M}_2\), hacer un diagrama de calor de cada matriz de incidencia a posteriori ordenada de acuerdo con la partición de referencia. Presentar todas las visualizaciones en un solo panel de \(2\times3\) o \(3\times2\) para reconocer las características propias de cada matriz de incidencia.
par(mfrow = c(2,3), mar = c(2.75,2.75,1.5,0.5), mgp = c(1.7,0.7,0))
for (j in 1:6) {
load(file = paste0("muestras","_",j,"_","M2.RData"))
A <- get_incidence_matrix(muestras$XI)
heat.plot0(mat = A, labs = NA, tick = F, main = paste("M2 : D",j))
}
Interpretar los hallazgos obtenidos en los numerales 5., 6., y 7.. Utilizar máximo 1000 palabras.