Bases: VIPRSGrid
The VIPRSBMA
class is an extension of the VIPRSGrid
class that
implements Bayesian model averaging for the VIPRS
models in the grid.
Bayesian model averaging is a technique that allows us to combine the
results of multiple models by weighting them according to their evidence.
In this context, we weigh the model by their final ELBO values.
For more details on the BMA procedure implemented here, refer to the
Supplementary material of:
Zabad S, Gravel S, Li Y. Fast and accurate Bayesian polygenic risk modeling with variational inference.
Am J Hum Genet. 2023 May 4;110(5):741-761. doi: 10.1016/j.ajhg.2023.03.009.
Epub 2023 Apr 7. PMID: 37030289; PMCID: PMC10183379.
Source code in viprs/model/gridsearch/VIPRSBMA.py
| class VIPRSBMA(VIPRSGrid):
"""
The `VIPRSBMA` class is an extension of the `VIPRSGrid` class that
implements Bayesian model averaging for the `VIPRS` models in the grid.
Bayesian model averaging is a technique that allows us to combine the
results of multiple models by weighting them according to their evidence.
In this context, we weigh the model by their final ELBO values.
For more details on the BMA procedure implemented here, refer to the
Supplementary material of:
> Zabad S, Gravel S, Li Y. Fast and accurate Bayesian polygenic risk modeling with variational inference.
Am J Hum Genet. 2023 May 4;110(5):741-761. doi: 10.1016/j.ajhg.2023.03.009.
Epub 2023 Apr 7. PMID: 37030289; PMCID: PMC10183379.
"""
def __init__(self,
gdl,
grid,
**kwargs):
"""
Initialize the `VIPRSBMA` model.
:param gdl: An instance of `GWADataLoader`
:param grid: An instance of `HyperparameterGrid`
:param kwargs: Additional keyword arguments for the VIPRS model
"""
super().__init__(gdl, grid=grid, **kwargs)
def average_models(self, normalization='softmax'):
"""
Use Bayesian model averaging (BMA) to obtain final weights for each parameter.
We average the weights by using the final ELBO for each model.
:param normalization: The normalization scheme for the final ELBOs.
Options are (`softmax`, `sum`).
:raises KeyError: If the normalization scheme is not recognized.
"""
if self.n_models < 2:
return self
# Extract the models that converged successfully:
models_to_keep = np.where(self.models_to_keep)[0]
elbos = self.history['ELBO'][-1][models_to_keep]
if normalization == 'softmax':
from scipy.special import softmax
weights = np.array(softmax(elbos))
elif normalization == 'sum':
weights = np.array(elbos)
# Correction for negative ELBOs:
weights = weights - weights.min() + 1.
weights /= weights.sum()
else:
raise KeyError("Normalization scheme not recognized. "
"Valid options are: `softmax`, `sum`. "
"Got: {}".format(normalization))
if int(self.verbose) > 1:
logging.info("Averaging PRS models with weights:", weights)
# Average the model parameters:
for param in (self.pip, self.post_mean_beta, self.post_var_beta,
self.var_gamma, self.var_mu, self.var_tau,
self.eta, self.zeta, self.q):
for c in param:
param[c] = (param[c][:, models_to_keep]*weights).sum(axis=1)
# Set the number of models to 1:
self.n_models = 1
return self
|
__init__(gdl, grid, **kwargs)
Initialize the VIPRSBMA
model.
Parameters:
Name |
Type |
Description |
Default |
gdl |
|
An instance of GWADataLoader
|
required
|
grid |
|
An instance of HyperparameterGrid
|
required
|
kwargs |
|
Additional keyword arguments for the VIPRS model
|
{}
|
Source code in viprs/model/gridsearch/VIPRSBMA.py
| def __init__(self,
gdl,
grid,
**kwargs):
"""
Initialize the `VIPRSBMA` model.
:param gdl: An instance of `GWADataLoader`
:param grid: An instance of `HyperparameterGrid`
:param kwargs: Additional keyword arguments for the VIPRS model
"""
super().__init__(gdl, grid=grid, **kwargs)
|
average_models(normalization='softmax')
Use Bayesian model averaging (BMA) to obtain final weights for each parameter.
We average the weights by using the final ELBO for each model.
Parameters:
Name |
Type |
Description |
Default |
normalization |
|
The normalization scheme for the final ELBOs. Options are (softmax , sum ).
|
'softmax'
|
Raises:
Type |
Description |
KeyError
|
If the normalization scheme is not recognized.
|
Source code in viprs/model/gridsearch/VIPRSBMA.py
| def average_models(self, normalization='softmax'):
"""
Use Bayesian model averaging (BMA) to obtain final weights for each parameter.
We average the weights by using the final ELBO for each model.
:param normalization: The normalization scheme for the final ELBOs.
Options are (`softmax`, `sum`).
:raises KeyError: If the normalization scheme is not recognized.
"""
if self.n_models < 2:
return self
# Extract the models that converged successfully:
models_to_keep = np.where(self.models_to_keep)[0]
elbos = self.history['ELBO'][-1][models_to_keep]
if normalization == 'softmax':
from scipy.special import softmax
weights = np.array(softmax(elbos))
elif normalization == 'sum':
weights = np.array(elbos)
# Correction for negative ELBOs:
weights = weights - weights.min() + 1.
weights /= weights.sum()
else:
raise KeyError("Normalization scheme not recognized. "
"Valid options are: `softmax`, `sum`. "
"Got: {}".format(normalization))
if int(self.verbose) > 1:
logging.info("Averaging PRS models with weights:", weights)
# Average the model parameters:
for param in (self.pip, self.post_mean_beta, self.post_var_beta,
self.var_gamma, self.var_mu, self.var_tau,
self.eta, self.zeta, self.q):
for c in param:
param[c] = (param[c][:, models_to_keep]*weights).sum(axis=1)
# Set the number of models to 1:
self.n_models = 1
return self
|