Simulation 3 (paper §4.3) stress-tests the model when the
true covariance is arbitrary (not low-rank) and varies
with a binary covariate. It also illustrates choosing the working
dimension K and checking robustness to it. The paper uses
,
,
and
;
a smaller design is used here.
library(BCAIA)
set.seed(2)
s <- 15; n <- 2 * s; J <- 40
subject <- rep(seq_len(s), 2)
xd <- rep(c(0, 1), each = s)
Xcov <- cbind(1, xd) # intercept + binary covariate
Xmean <- cbind(xd)
## two arbitrary sparse covariance matrices, one per level of xd
rand_cov <- function(J, sparsity = 0.85) {
A <- matrix(rnorm(J * J), J, J); A[abs(A) < sparsity * 2] <- 0
S <- tcrossprod(A) / J + diag(1, J); S
}
Sig0 <- rand_cov(J); Sig1 <- rand_cov(J)
alpha_s <- matrix(rnorm(s * J, 3, 1), s, J)
Y <- matrix(0, n, J)
for (i in seq_len(n)) {
Sig <- if (xd[i] == 0) Sig0 else Sig1
L <- chol(Sig + diag(1e-8, J))
Y[i, ] <- floor(exp(alpha_s[subject[i], ] + as.numeric(crossprod(L, rnorm(J)))))
}Choosing K from a clr-PCA scree rule
choose_K(Y, plot = TRUE)
#> [1] 19
#> attr(,"eigenvalues")
#> [1] 1.382640e+01 9.324728e+00 8.692113e+00 7.118524e+00 6.762344e+00
#> [6] 6.343753e+00 5.857729e+00 4.942973e+00 3.528089e+00 3.357174e+00
#> [11] 3.130019e+00 2.753344e+00 2.438689e+00 2.316600e+00 2.226240e+00
#> [16] 1.841705e+00 1.489687e+00 1.275955e+00 1.110679e+00 1.073295e+00
#> [21] 8.547790e-01 6.638565e-01 5.032603e-01 4.920572e-01 3.355124e-01
#> [26] 2.869716e-01 1.690666e-01 1.002683e-01 1.541650e-02 2.133646e-15
#> [31] 1.435907e-15 9.652194e-16 6.969157e-16 3.531268e-16 7.975653e-17
#> [36] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
Fitting
fit <- bcaia(Y, Xmean, Xcov, subject = subject, K = 25,
niter = 160000, burnin = 80000, thin = 10, seed = 1)#> BCAIA fit (subject model)
#> data: n = 30, J = 40, Pmean = 1, Pcov = 2, K = 10
#> subjects: s = 15
#> MCMC: 1000 iters, burn-in 500, thin 5 -> 100 saved samples
#> runtime: 0.5 min
Group-specific covariance estimates
S0 <- posterior_cor(fit, c(1, 0))
S1 <- posterior_cor(fit, c(1, 1))
op <- par(mfrow = c(1, 2), mar = c(2, 2, 2, 1))
image(S0, main = "rho-hat (xd = 0)", axes = FALSE)
image(S1, main = "rho-hat (xd = 1)", axes = FALSE)
par(op)Even though the model assumes a low-rank covariance regression, with
a sufficiently large K and the full chain it approximates
the arbitrary group-specific covariance structures well, and the
posterior estimates are robust to the choice of K (paper
§4.3 and Supp. Fig. 7).