Exact Model Enumeration & Bayesian Model Averaging

Python · R · Part 2 of the variable-selection arc — the conjugate route

Overview

Part 2 of the variable-selection arc: the conjugate route. Part 1 searched the model space with a spike-and-slab Gibbs sampler. But if the candidate set is small, we don't have to search at all — we can enumerate every model exactly. George & McCulloch (1997) showed how: put a conjugate prior on each model's coefficients so β\beta and σ2\sigma^2 integrate out analytically, leaving a closed-form marginal likelihood p(ymodel)p(y\mid\text{model}). With pp predictors there are 2p2^p models; for p20p\lesssim 20 we score all of them and get exact posterior model probabilities — no MCMC, no Monte-Carlo error. This reproduces Congdon's (2005) Example 3.3 on the cystic-fibrosis PEmax data (respiratory muscle strength in 25 patients against 9 clinical predictors), enumerating all 29=5122^9=512 models rather than working through them in forward stages.

p(yγ)    (1+g)(n1pγ)/2[1+g(1Rγ2)](n1)/2p(y\mid\gamma) \;\propto\; \frac{(1+g)^{(n-1-p_\gamma)/2}}{\big[\,1+g(1-R^2_\gamma)\,\big]^{(n-1)/2}}

The g-prior and the closed-form marginal likelihood

For a model indexed by an inclusion vector γ{0,1}p\gamma\in\{0,1\}^p, the conjugate choice is Zellner's gg-prior on the coefficients, βγσ2N(0,gσ2(XγXγ)1)\beta_\gamma\mid\sigma^2 \sim \mathcal N(0, g\sigma^2(X_\gamma^\top X_\gamma)^{-1}), with a reference prior p(α,σ2)1/σ2p(\alpha,\sigma^2)\propto 1/\sigma^2. Integrating out α,βγ,σ2\alpha,\beta_\gamma,\sigma^2 gives a marginal likelihood that depends on the data only through the model's Rγ2R^2_\gamma (Liang et al. 2008) — the numerator penalises size, the denominator rewards fit, an automatic fully-Bayesian Occam balance. The hyperparameter is g=n=25g=n=25, the unit-information prior that makes model comparison behave like BIC and matches R's BAS (alpha = n) exactly. The algorithm is a deterministic sweep, not a Markov chain: center yy and XX; for each of the 2p2^p subsets regress by least squares, read off Rγ2R^2_\gamma, and evaluate the closed-form logp(yγ)\log p(y\mid\gamma); normalise over all models for exact posterior model probabilities; then sum over models containing predictor jj for its inclusion probability, and weight the gg-shrunk estimates for model-averaged coefficients. Because it is exact, there is nothing to converge or diagnose — the only limit is that 2p2^p must be enumerable (beyond p25p\approx 25 one falls back to Part 1's search). The engine is a self-contained bvsenum.py.

Results

Three predictors carry the signal — weight (0.64), FEV1 (0.60) and BMP (0.49) have the highest inclusion probabilities, the other six at or below the neutral 0.5 line — clinically sensible, since respiratory muscle strength tracks body size/nutrition and lung function. But no single model dominates: the best model, weight + bmp + fev1, holds only ~5% of the posterior; dozens are plausible, and with 25 patients and 9 correlated predictors which model is genuinely uncertain — a point a stepwise "winner" hides entirely. The posterior over model size peaks at 3–4 predictors (averaging ~3.4) — the gg-prior's built-in Occam penalty resisting the urge to use all nine. This is why we average: inclusion probabilities and model-averaged coefficients summarise all 512 models weighted by evidence rather than betting on one fit chosen under uncertainty. Enumeration and search agree on the substance: the Part-1 spike-and-slab MCMC — a different prior reached by sampling — puts the same leading predictors up front (weight and FEV1 clearly, with BMP still among the leaders); the magnitudes and exact ordering differ a little (inclusion probabilities are genuinely prior-dependent), but the set of predictors that matters is robust to both prior and algorithm. Seeing them coincide here, where we can enumerate, is what licenses trusting the search where we cannot. The exact marginal likelihood is the same object R's BAS computes.

Notebooks

Downloads

References