Put flat priors on the intercept and main effects and N(0,1/λ) priors on pairwise interactions, run MCMC (MCMCpoisson, MCMCpack), drop interactions whose |posterior mean| / posterior SD falls below a threshold τ, and refit. Recommended defaults: variance 1 (λ=1) and τ=2.
Overview
Idea: allow the prior to shrink interactions toward zero without constraining the intercept or main effects (which determine list sizes and the dark figure). A true spike-and-slab prior (atom at zero plus a continuous part) is the ideal; thresholding approximates it (Johnstone and Silverman 2004) and standard MCMC software cannot do the mixed prior, so exact implementation is “a topic for future research”.
Main Content
Bayesian/threshold algorithm
Model: Poisson log-linear (Eq. 1) of Silverman 2020 - Poisson Log-Linear Model for Multiple Lists.
Step 1 (prior).μ,αi,βij independent; μ and αi have improper uniform priors on (−∞,∞); βij∼N(0,1/λ), λ≥0 (λ=0 means improper uniform). Fit by MCMC.
Step 2 (threshold). Constrain to zero every βij for which |posterior mean| / posterior SD does not exceed τ, then rerun the MCMC with those interactions omitted. τ=0 means no thresholding.
Tuning: expβij is the factor by which a case is more or less likely to be on both i and j than under independence, so βij far outside ±1 is implausible; prior variance 1/λ with λ in 1 to 10 suggested. Liberal threshold τ=2 (include interactions not clearly spurious); parsimonious τ=5 (admittedly arbitrary).
Implementation (Sec. 6.2).
MCMCpoisson does not handle a mixture of improper-uniform and finite-variance priors; if λ>0, MCMCfit in modslavmse gives the intercept and main effects a large finite variance 104.
With a proper prior the empty-overlap problem disappears because the posterior is proper; improper uniform is computationally fastest.
The total population estimate is posterior draws of eμ plus observed cases (quantiles reported include observed data).
Examples
Sketch in PyMC (untested)
A Bayesian log-linear MSE with Gaussian interaction prior; the thresholding step is applied post hoc from the first fit.
import numpy as np, pymc as pm, itertoolsK = 4cells = [h for h in itertools.product([0,1], repeat=K) if any(h)]H = np.array(cells) # (2^K-1, K)pairs = list(itertools.combinations(range(K), 2))P = np.stack([H[:, i]*H[:, j] for i, j in pairs], 1) # pair indicatorsy = np.array([...]) # observed counts, same order as cellswith pm.Model() as m: mu = pm.Flat("mu"); alpha = pm.Flat("alpha", shape=K) beta = pm.Normal("beta", 0, 1.0, shape=len(pairs)) # variance 1, Silverman default log_lam = mu + H @ alpha + P @ beta pm.Poisson("y", pm.math.exp(log_lam), observed=y) pm.Deterministic("dark", pm.math.exp(mu)) idata = pm.sample()# threshold: keep pairs with |mean|/sd > 2, refit with only those columns
Pairwise “interaction” terms among overlapping data sources (panels, CRM lists, ad-server logs) are the analogue of list dependence. Shrinking weak interactions while leaving main effects unpenalised mirrors a standard MMM practice: do not shrink the quantities the decision depends on (baseline and main effects), do regularise the long tail of possible interactions.