I have implemented ELBO for M&M model based on write up in this document. See Section 8 for derivation details; also Section B for an independent re-derivation from Yuxin Zou in checking my work.
(the analytic form are not identical due to different simplifications but I coded both up and checked they agree).
susieR
implementation in univariate case¶Here I simulate one trait and run with susieR::susie
as well as mvsusieR::susie
to check if the elbo agree.
library(mvsusieR)
set.seed(2)
I pick L=5
and simulate a univariate trait,
L = 5
dat = mvsusie_sim1(r=1)
Then run SuSiE and get the ELBO,
res = susieR::susie(dat$X,dat$y,L=L,scaled_prior_variance=0.2,estimate_residual_variance=F,estimate_prior_variance=F)
res$elbo
res = susieR::susie(dat$X,dat$y,L=L,scaled_prior_variance=0.2,estimate_residual_variance=T,estimate_prior_variance=F)
res$elbo
res = susieR::susie(dat$X,dat$y,L=L,scaled_prior_variance=0.2,estimate_residual_variance=T,estimate_prior_variance=T)
res$elbo
mvsusieR
's Bayesian multivariate regression module with SuSiE¶I have implemented the multiple regression in this class in mvsusieR
package. On the mvsusieR
interface this is triggered by setting prior V
as a scalar and make input Y
a one column matrix,
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=0.2,compute_objective=T,estimate_residual_variance=F,estimate_prior_variance=F)
res$elbo
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=0.2,compute_objective=T,estimate_residual_variance=T,estimate_prior_variance=F)
res$elbo
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=0.2,compute_objective=T,estimate_residual_variance=T,estimate_prior_variance=T)
res$elbo
The output is identical to using susieR
.
mvsusieR
's MASH regression module with SuSiE¶Here I create a degenerated MASH regression module implemented in mvsusieR
. "Degenerated" means it has only one phenotype, and the prior is also a trivial one-component 1 by 1 matrix of 0.2 * var(Y)
. Here we use EE
model in MASH (alpha = 0
).
The difference in code between this and previous section in computing ELBO can be found in this function for computing the L-th KL: compute_expected_loglik_partial() and this function: compute_objective() for finalizing the ELBO. The univariate and multivariate cases are distinguished by if ... else
statement.
m_init = mvsusieR:::MashInitializer$new(list(matrix(0.2*var(dat$y))), 1, alpha=0)
m_init$mash_prior
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=m_init,compute_objective=T, estimate_residual_variance=F,estimate_prior_variance=F)
res$elbo
The output is also the same as previous calculations.
Now using the same code, but more phenotypes, R = 5
, and still using a very simple prior for the MASH part,
set.seed(2)
dat = mvsusie_sim1(r=5)
m_init = mvsusieR:::MashInitializer$new(list(dat$V), 1, alpha=0)
m_init$mash_prior
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=m_init,compute_objective=T,estimate_residual_variance=F,estimate_prior_variance=F)
res$elbo
and with a different seed:
set.seed(1)
dat = mvsusie_sim1(r=5)
m_init = mvsusieR:::MashInitializer$new(list(dat$V), 1, alpha=0)
res = mvsusieR::mvsusie(dat$X,dat$y,L=L,prior_variance=m_init,compute_objective=T,estimate_residual_variance=F,estimate_prior_variance=F)
res$elbo