Variable Selection
Which predictors belong in the model? The Bayesian answer is not a single winner but a posterior over the whole model space — inclusion probabilities and a ranked list of models, with honest uncertainty. This arc builds that machinery from scratch: stochastic search variable selection (SSVS) with George–McCulloch spike-and-slab priors; exact model enumeration with conjugate g-priors and Bayesian model averaging; VAR restriction search that selects a whole system's lag structure and error covariance at once; log-linear model selection that chooses which associations belong in a contingency table; and, when even the model's size is unknown, a trilogy of trans-dimensional samplers — a reversible-jump change-point model, a Dirichlet-process mixture, and free-knot splines — inferring the number of regimes, of components, and of knots. Further nodes extend the reach across outcome types — a logistic selector (Pólya–Gamma augmentation carries the whole Gaussian machinery over to a binary outcome) and a survival selector that handles censored time-to-event data — and across scale: a p ≫ n genomics horseshoe, where continuous global-local shrinkage replaces discrete indicators and a specialised sampler makes selection over thousands of predictors routine. Each is cross-checked across Python and R.
What an inclusion probability is, and where its zero point sits. Every method below reports the same headline number: the posterior inclusion probability, the share of the posterior weight sitting on models that contain a given predictor. If half the probability lands on models including weight, weight’s inclusion probability is 0.5. Three things about it are easy to get wrong. Its neutral point is not zero — it is whatever the prior said, and these pages give each predictor an even chance of being in or out, so 0.5 is the number a predictor starts with: above it the data have raised the odds, below it the data have lowered them, and 0.49 is not weak evidence for a predictor but evidence that went the other way. It is not an effect size and not a p-value — a coefficient can be large and excluded, or small and kept. And it is conditional: it asks whether a predictor earns its place given the others, not whether it moves with the outcome on its own. In the heart-disease example below, adiposity tracks the disease about as closely as LDL cholesterol does (r = +0.25 against +0.26) and is dropped anyway, at inclusion 0.08, because whatever it knows is already in the model through the predictors it shares its information with. That gap between marginal association and conditional necessity is the whole reason to run a selection at all.
Marginal likelihood, and the Occam penalty nobody writes down. To weigh one model against another, each needs a score: the marginal likelihood, the probability that model assigned to the data actually observed — averaged over every parameter value its prior allowed, before seeing anything. The averaging is what turns it into a selection criterion. A model with more free parameters can accommodate more datasets it might have seen, so it must spread the same total probability more thinly across them, and any single dataset receives less of it. Complexity is therefore penalised as a consequence of the integral, not added by hand the way AIC and BIC bolt on a parameter-count term — the automatic Occam balance the pages below refer to. The ratio of two marginal likelihoods is a Bayes factor. The price is that the integral runs over the entire prior, which makes it far more sensitive to that prior than any posterior mean would be; that is why the priors here are picked for tractability as much as realism, conjugate ones giving the integral in closed form and a Laplace approximation standing in where the likelihood is not conjugate.
Why the answer is a distribution over models, not a winner. Once every model carries a probability there is no need to choose one. Bayesian model averaging forms the quantity of interest — a coefficient, a prediction — as a weighted average across models, each weighted by its posterior probability, so a predictor present in half the credible models contributes half as much. Why bother is visible in Part 2: the single best of 512 models holds about 5% of the posterior, so a procedure reporting it alone discards 95% of what the data support. Stepwise selection compounds that by quoting the winner’s standard errors as though the search that produced the winner had never happened. Model averaging keeps the uncertainty about which model inside the answer instead of dropping it at the last step.
Collapsing, and why a change of dimension needs no Jacobian. One phrase recurs below — the coefficients are integrated out, or collapsed. It is the same operation each time: when the prior is conjugate the continuous parameters can be removed analytically, leaving a probability that depends only on the discrete structure — which predictors are in, where the change-points fall, how the points are grouped. Two things follow. The sampler then explores a far smaller space, which is why these purpose-built engines mix well where general-purpose ones labour. And when the model’s size changes there is no continuous parameter vector to be matched across the two dimensions, so the change-of-variables term — the Jacobian — that a reversible jump normally has to supply is not needed at all. That is what no Jacobian means in Parts 5 to 7, and it is why those samplers are as short as they are.
The three things this arc actually produces
All three panels are drawn from the runs the notebooks below publish. A is the Part-1 SSVS sampler on the turnip-greens data, B the Part-2 enumeration of the cystic-fibrosis models, and C the three trans-dimensional samplers of Parts 5 to 7.
A is the mechanism, and it is a mixture rather than a switch. The prior offers each coefficient two homes — a spike of standard deviation 0.05 that pins it at zero, and a slab twenty times wider that lets it be anything — and the sampler chooses afresh every sweep. A dropped predictor spends 94% of its draws inside the spike and ends with a posterior standard deviation of 0.08; a kept one is six and a half times wider and sits clearly away from zero. But notice what the kept predictor also does: with an inclusion probability of 0.69 it spends 31% of its draws switched off, and those draws are what piles the red mass up at zero. That is what an inclusion probability is — the fraction of the time the coefficient was in the slab — and it is why these models return a distribution over which predictors matter rather than a verdict.
B puts that number where it can be read against the only reference point that makes it meaningful. The dashed line is 0.5, the value every predictor carries before any data arrive, so the question is never how large an inclusion probability is but which side of that line it has moved to. Two predictors cross it. BMP, usually reported as the third member of the signal, sits at 0.492 — fractionally on the wrong side. And the two engines, which agree closely at the top, disagree about the order behind it: the sampled run lifts age above BMP, reversing third and fourth. When the gaps are smaller than the disagreement between two correct methods, the ranking is not a result.
C is the arc's last move, and putting the three side by side shows what a posterior over dimension buys. Each names a favourite — two change-points, four components, five knots — and each attaches a very different confidence to it. The coal-mining series gives its mode 51% of the posterior, the spline 44%, and the galaxy data only 28%, with almost as much mass on five components as on four. A method that reported only the winner would return “2”, “4” and “5” with equal apparent authority and conceal the fact that one of the three answers is barely an answer at all. The height of the tallest bar is the part that a single number throws away.
What a posterior over models actually looks like
Part 2 scores all 512 models of the cystic-fibrosis data exactly — no sampling, no approximation. These are the five most probable, and the share of belief each one holds.
The winner is right about one time in twenty. Reading down the list is what makes the data’s actual position legible: weight appears in every one of them, and past that the evidence stops resolving. The second most probable answer is that weight is the only thing that matters; the third adds RV, a predictor neither of the two above it contains. Those are not small variations on one finding, they are different findings, and the data does not separate them. A procedure that reports the top row alone is not summarising this list — it is concealing it, and then quoting standard errors as though the choice had been free. Averaging across the whole list is the alternative, and it is what every page here does: the average model carries 3.4 predictors.
How the ten examples relate
The arc asks one question three times over, and each time the question gets harder. Start with a trunk; the entries indented beneath it assume it and change one thing.
Which ones belong?
Nine lung-function measures, six growing-condition terms, eighteen VAR lag coefficients — which of them earn their place?
1 · Stochastic search (SSVS)a sampler wanders the model space — the method that scales 3 · VAR restriction searchthe same search on a whole system, selecting the error covariance too 2 · Exact enumeration & BMAwhen the list is short enough, score every model instead of searching 4 · Log-linear selectionthe same scoring over the associations in a contingency tableHow many pieces does it have?
Not which parts belong, but how many parts there are — the model’s own size becomes the unknown.
5 · Reversible-jump change-pointsGreen’s birth/death/shift moves — how many regime shifts? 6 · Dirichlet-process mixturesthe same jumps, run on how many components generated the data 7 · Free-knot splinesand on how many bends a curve has, and where they sitThe same question, harder data
Four thousand predictors against seventy samples. A yes/no outcome. Patients still alive when the study stopped.
8 · Horseshoe at scaletoo many predictors to switch on and off, so shrink continuously instead 9 · Logistic selectionPart 1’s sweep unchanged, carried to a binary outcome 10 · Survival selectionand to time-to-event data, where most outcomes are never observedParts 8 to 10 are all branches of Part 1 — its spike-and-slab step survives every one of them intact, which is the arc’s real claim: the selection machinery is separable from the model it is applied to.
Stochastic Search Variable Selection (SSVS)
Part 1 of the variable-selection arc: spike-and-slab, from scratch. Given a pile of candidate predictors, George & McCulloch (1993) attach to each coefficient a latent inclusion indicator and a spike-and-slab prior — a narrow spike pinning switched-off coefficients near zero, a wide slab allowing a real effect — and let a Gibbs sampler wander through the model space (the stochastic search) — a posterior over 2p models. Because the spike is a proper normal, every full conditional is closed form; the indicator update — a Bernoulli from the ratio of slab to spike density at the current coefficient — is the search. Reproducing Congdon's turnip-greens riboflavin example (Draper–Smith), the sampler recovers that soil-moisture tension alone carries the signal (posterior inclusion ~0.69, the "moisture only" model most visited), delivering not a point estimate but posterior inclusion probabilities and a ranked model space. The from-scratch Gibbs and a PyMC compound sampler agree to within a few points — showing why George–McCulloch derived a fully-conjugate scheme for the sharp spike/slab geometry.
View example →Exact Model Enumeration & Bayesian Model Averaging
Part 2 of the variable-selection arc: the conjugate route. Where
Part 1 searched the model space, a small candidate set
can be enumerated exactly. George & McCulloch (1997) put a
conjugate Zellner g-prior on each model so the coefficients integrate out, leaving a
closed-form marginal likelihood that depends on the data only through the model's
R² — an automatic Occam balance of fit against size. Scoring all 2⁹ = 512 models of
the cystic-fibrosis PEmax data gives exact posterior model probabilities, inclusion
probabilities, and model-averaged coefficients — no MCMC. Weight (0.641) and FEV1 (0.596)
clear the neutral 0.5 line and BMP (0.492) sits a fraction below it, yet the best single model holds
only ~5% of the posterior: the honest
headline is uncertainty, which stepwise selection hides. The exact enumeration and Part 1's
spike-and-slab search agree on which predictors matter — licensing the search where enumeration is
infeasible. Cross-checked against PyMC and R's BAS.
SSVS for VARs — Bayesian Restriction Search
Part 3 of the variable-selection arc: restriction search on a whole system. An unrestricted VAR is famously over-parameterised, and George, Sun & Ni (2008) turn Part 1's spike-and-slab loose on it — selecting on two fronts at once: which lag coefficients are real, and which contemporaneous links are real (via spike-and-slab on the off-diagonals of the error-precision Cholesky factor). On a US monetary VAR the search discovers, rather than imposes, textbook dynamics — a Taylor-rule-like interest-rate equation — switches off about half the lag terms, and prunes the covariance too (keeping ffr↔inflation and ffr↔output, dropping the direct output↔inflation link). Unlike a shrinkage prior it returns genuine 0/1 restrictions and their probabilities — a posterior over VAR specifications — and it is the only method in the series that selects the error covariance as well as the mean. The selection counterpart to the Minnesota and horseshoe shrinkage priors used elsewhere. Cross-checked against PyMC and base R.
View example →Bayesian Selection of Log-Linear Models
Part 4 of the variable-selection arc: selection for categorical data. For a contingency table, "which predictors matter" becomes "which associations are present". Albert (1996) models the cell counts as Poisson with a log-linear mean, puts robust Cauchy priors on the interaction terms, and compares models by marginal likelihood — so the data, not the prior's tails, decide. The showcase is the Berkeley admissions table, where aggregate figures suggest gender bias: the selection asks whether a direct admission–gender association survives once department is accounted for. It does not — the conditional-independence model carries 90% of the posterior (Admit:Dept and Gender:Dept certain, Admit:Gender only ~0.10) — resolving Simpson's paradox as model selection. The same spike-and-slab / marginal-likelihood logic as Parts 1–3, now over the interactions of a log-linear model. Cross-checked against PyMC and R.
View example →Reversible-Jump MCMC — Inference over Model Dimension
Part 5 of the variable-selection arc — the closing node. Every earlier method chose among models of fixed size; the last question is harder: how many components does the model have? When the parameter's dimension is itself unknown, an ordinary sampler cannot move — the vector changes length. Green's (1995) reversible-jump MCMC constructs birth / death / shift moves that jump between dimensions while preserving detailed balance. On Green's flagship coal-mining disaster series it infers the number of change-points jointly with their locations and rates: a change is certain, the posterior favours two regime shifts (a major drop ~1890 and a smaller one ~1947) — the celebrated "single 1890 change-point" is just the k = 1 slice. Collapsing the conjugate rates lets the jumps move over discrete partitions with no Jacobian. It carries the arc's idea — let the data weigh the models — from selecting coefficients to selecting the model's very size. Cross-checked against PyMC and base R.
View example →Dirichlet-Process Mixtures — How Many Components?
Part 6 of the variable-selection arc: the mixture face of unknown dimension. Where
Part 5 asked "how many change-points?", its sibling asks
"how many components generated this data?" — a mixture whose number of components
K is itself a parameter. On the benchmark galaxy-velocity data, a
from-scratch collapsed Dirichlet-process sampler (Neal's Algorithm 3) integrates out
each Gaussian component analytically and lets a Chinese-restaurant allocation open and close
components — trans-dimensional moves with no Jacobian, the same recipe as Part 5. The
posterior on K peaks at 4 but spreads over 3–7: the honest answer is a
distribution over the number of components, not a single count. The collapsed sampler, a PyMC
stick-breaking DP, and R's mclust (EM + BIC) all agree on four — three philosophies,
one answer — completing the unknown-dimension pair (change-points and mixture
components) that caps the arc.
Free-Knot Splines — an Unknown Number of Knots
Part 7 of the variable-selection arc: nonparametric curve fitting, the third
unknown-dimension problem. A cubic spline bends at its knots — but how many, and
where? DiMatteo, Genovese & Kass (2001) let the number of knots itself
be inferred, the spline analogue of the change-point and
mixture-component samplers. A from-scratch free-knot RJMCMC
integrates out the coefficients and moves knots by birth / death / relocation, then
averages the curve over all sampled configurations. On a curve with a sharp peak the
posterior favours five knots (0.44, with six close behind at 0.38 — inferred, not assumed) and
migrates them to the curvature — capturing the peak (RMSE 0.014) where a PyMC
penalized spline, spreading one smoothness everywhere, oversmooths it (0.067; R's mgcv,
at 18.6 effective degrees of freedom, lands between the two at 0.025). Selecting where the flexibility goes beats
applying it uniformly — completing the unknown-dimension trilogy (change-points,
components, knots). Cross-checked against PyMC and R.
The Horseshoe at Scale — Selection when p ≫ n
Part 8 of the variable-selection arc: genomics-scale shrinkage. Real selection is
often thousands of predictors, tens of samples — where
enumeration (2⁴⁰⁸⁸ models) and discrete
spike-and-slab (4,088 indicators) both break down. The
horseshoe (Carvalho–Polson–Scott) instead shrinks: a global scale pulls
everything toward zero while heavy-tailed local scales let a few coefficients escape — continuous,
essentially parameter-free selection. On the riboflavin benchmark (n = 71,
p = 4,088 genes) a from-scratch Gibbs sampler — Makalic–Schmidt augmentation plus the
Bhattacharya O(n²p) coefficient draw — drives the median shrinkage weight to 0.998
and cleanly surfaces the driver genes YOAB and YXLE in under 10 seconds
(9.8 s, against 161 s for general-purpose NUTS on the same problem — a 16× gap). The lesson: when p ≫ n the algorithm, not just the prior,
is the enabling idea — and the reliable output is the shrinkage ranking, not individual near-zero
estimates. Cross-checked against PyMC and the glmnet lasso.
Logistic Variable Selection via Pólya–Gamma SSVS
Part 9 of the variable-selection arc: selection for a binary outcome. Most applied
problems have a yes/no response, which breaks the Gaussian conjugacy the earlier notebooks relied on.
Pólya–Gamma augmentation (Polson–Scott–Windle) fixes it — one latent weight per
observation makes the logistic likelihood conditionally Gaussian, so the exact
same spike-and-slab sweep carries over. On the
South African Heart Disease data both the SSVS search and an exact enumeration of all
2⁹ logistic models keep the same five risk factors — age, family history, tobacco,
type-A, LDL — dropping the body-size measures whose association is only marginal (selection
sees through the confounding). And selection is free: the five-variable model matches
the full model's predictions (r = 0.985) and generalizes slightly better out of sample. Bridges
Part 1 and Part 2 to binary
data. Cross-checked against PyMC and R's BAS.
Survival Variable Selection with Censored Data
Part 10 of the variable-selection arc: time-to-event outcomes, and the complication
no earlier notebook faced — censoring. When a study ends most patients are still
alive, so their survival time is known only to exceed their follow-up. A from-scratch
Weibull proportional-hazards spike-and-slab handles it through the
cumulative-hazard term — subtracted for every subject, so a censored patient
correctly contributes "survived at least this long" — while the
Part-1 inclusion step is untouched. On the Mayo
PBC data it recovers the hand-built natural-history model (bilirubin, age, edema,
albumin, prothrombin — plus stage and copper) and correctly declines the ineffective
treatment (inclusion ≈ 0.10). A parametric Weibull SSVS, PyMC, and R's Cox-based
bic.surv agree — the selection is a property of the proportional-hazards structure, not
the baseline form. This completes the arc's outcome types — continuous, counts,
binary, and now time-to-event. Cross-checked against PyMC and R.