Multivariate Bayesian variable selection regression

A smaller example of prior variance scalar estimate

This is continuation of previous notebook but using smaller example and more explicit code to show the problem. The data can be downloaded here.

The problems from previous notebook are:

  1. EM converges slowly
  2. The estimated prior variane scalar seems smaller than what we expect based on the coefficient estimate itself.

This notebook focuses on understanding 2. Therefore we use optim based result and manually check for a couple of iterations the inference for the 1st and 2nd moments, see if they are in agreement with the estimates.

In [1]:
attach(readRDS('em_optim_difference.rds'))

Here I use 15 conditions (this is enough conditions to show EM slow convergence issue),

In [2]:
R = 15
Y1 = Y[, c(1:R)]
resid_Y1 = resid_Y[c(1:R), c(1:R)]
V1 = matrix(1,R,R)
true_coef = meta$true_coef[,c(1:R)]

To simplify, I use codes from BayesianMultivariateRegression class from mvsusieR package which is a single component multivariate prior (not a mixture prior).

IBSS done manually

Here I run single effect models manually for L=2, using save_var to save posterior covariance matrix

In [3]:
devtools::load_all('~/GIT/software/mvsusieR')
d = DenseData$new(X,Y1)
d$standardize(TRUE,TRUE)
m1 = SingleEffectModel(BayesianMultivariateRegression)$new(ncol(X), resid_Y1, V1)
m2 = SingleEffectModel(BayesianMultivariateRegression)$new(ncol(X), resid_Y1, V1)
Loading mvsusieR

Loading required package: mashr

Loading required package: ashr

The first iteration

In [4]:
d$add_to_residual(m1$predict(d))
m1$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m1$predict(d))
d$add_to_residual(m2$predict(d))
m2$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m2$predict(d))
In [5]:
fitted = d$compute_Xb(m1$posterior_b1 + m2$posterior_b1)
d$compute_residual(fitted)

Now take a look at position 129, whose signal is captured by L2 with PIP > 0.9, to check the 2nd moment estimate and prior variance scalar,

In [6]:
m2$pip[129]
0.989863645087472
In [7]:
sum(diag(tcrossprod(m2$posterior_b1[129,])))/R
0.00166608931066299
In [8]:
m2$prior_variance
0.00170466773300059

The 2nd iteration

In [9]:
d$add_to_residual(m1$predict(d))
m1$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m1$predict(d))
d$add_to_residual(m2$predict(d))
m2$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m2$predict(d))
In [10]:
m2$pip[129]
0.999912072785095
In [11]:
sum(diag(tcrossprod(m2$posterior_b1[129,])))/R
0.00312592162254299
In [12]:
m2$prior_variance
0.00313137637417771

The 3rd iteration

In [13]:
d$add_to_residual(m1$predict(d))
m1$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m1$predict(d))
d$add_to_residual(m2$predict(d))
m2$fit(d, estimate_prior_variance_method = 'optim', save_var = TRUE)
d$remove_from_residual(m2$predict(d))
In [14]:
sum(diag(tcrossprod(m2$posterior_b1[129,])))/R
0.0037375502970709
In [15]:
m2$prior_variance
0.00374254134042344

It seems to be close to convergence. The estimate from this model is different from the simulated truth,

In [16]:
m2$posterior_b1[129,]
  1. 0.06113550766184
  2. 0.06113550766184
  3. 0.06113550766184
  4. 0.06113550766184
  5. 0.06113550766184
  6. 0.06113550766184
  7. 0.06113550766184
  8. 0.06113550766184
  9. 0.06113550766184
  10. 0.06113550766184
  11. 0.06113550766184
  12. 0.06113550766184
  13. 0.06113550766184
  14. 0.06113550766184
  15. 0.06113550766184
In [17]:
true_coef[129,]
  1. -0.451579520293967
  2. 0.212362419670355
  3. -0.23139926245904
  4. 1.29082044865503
  5. -0.139192877987568
  6. 0.45860797023633
  7. 1.19081004850437
  8. 0.519507177038623
  9. -0.444040958330359
  10. 0.552882389431176
  11. 1.02044255171292
  12. -0.671814615437313
  13. 0.648295380611219
  14. 0.904728920517463
  15. 0.56318766496157

I think the disagreement is understandable because the "all shared" prior model is very much mis-specified for these true coefficients.

Notice previous notebook I made a mistake using the coefficient based on rescaled data,

In [22]:
wrong_b1 = d$rescale_coef(m2$posterior_b1)[130,]
In [23]:
sum(diag(tcrossprod(wrong_b1)))/R
0.0986839903507364

This is inconsistent with estimated prior scalar because of the scale issue.


Copyright © 2016-2020 Gao Wang et al at Stephens Lab, University of Chicago