Rosenman 2020 - Hierarchical Bias Model Sketch for Few Holdouts
Summary
The paper’s per-stratum bias and its estimated shrinkage have a direct Bayesian reading: put a hierarchical prior on the bias, , observe the bias only where a holdout exists, and use the posterior of to correct the propensity estimate in campaigns without a holdout. With the posterior weight on the RCT equals the paper’s with replaced by . This note records that equivalence and a PyMC sketch for the E103 setting. Synthesis; code is untested.
Overview
Setting (E103-style). campaigns, each with an observational (propensity-adjusted) lift estimate (large sample, small variance) but only with a randomised ghost-ad/holdout estimate (small sample, large variance). The question: how much to trust in the campaigns with no holdout.
Mapping to the paper. Strata campaigns; Assumption 2 (common effect) the same estimated both ways; the unknown stratum bias of the observational estimate the bias that the hierarchical model learns; the sampling variances (treated as known from standard errors).
Main Content
Model
For campaign with covariates (targeting breadth, reach, audience type, …):
The bias is assumed to be additive on the effect scale (the paper’s ); if the bias is multiplicative, work on the log scale or model .
Marginal model (effects integrated out)
For holdout campaigns, subtracting the two estimates removes :
This is identified from the holdouts alone and has no funnel in : sample in this marginal form, then recover and afterwards (the centred form with sampled directly has the usual funnel as ; use a non-centred parameterisation if sampling them jointly).
Posterior weight equals the paper's shrinkage weight (when )
Conditional on and with a flat prior on , the posterior mean of for a holdout campaign is
Compare the oracle : the bias second moment is replaced by the prior bias variance , and is learned from the holdouts (empirical Bayes in via the discrepancy ; fully Bayesian here). Weights are per-campaign, i.e. closer to variance-weighted than to the common-factor .
For a campaign without a holdout, is predicted from the observational estimate and the posterior predictive of the bias:
(plug-in sketch; the full posterior integrates over ). Uncertainty is dominated by when is small - a few holdouts cannot tell much about (very weakly identified with small), so its prior matters (use a half-normal with scale set by plausible bias, and report prior sensitivity).
PyMC 5 sketch (untested)
import numpy as np, pymc as pm
def bias_model(tau_o, se_o, X, holdout_idx, tau_r, se_r):
"""tau_o, se_o: observational estimate and SE for all C campaigns; X: C x p campaign covariates (standardised);
holdout_idx: indices with a holdout; tau_r, se_r: holdout estimates and SEs for those campaigns."""
C, p = X.shape
with pm.Model() as m:
gamma = pm.Normal("gamma", 0, 0.5, shape=p) # covariates of the bias
mu_bias = pm.Normal("mu_bias", 0, 0.5) # average bias
tau_xi = pm.HalfNormal("tau_xi", 0.3) # bias heterogeneity; weakly identified with few holdouts
# marginal likelihood for holdout campaigns (tau_c integrated out)
d = tau_o[holdout_idx] - tau_r
sd = pm.math.sqrt(se_o[holdout_idx]**2 + se_r**2 + tau_xi**2)
pm.Normal("d_obs", mu_bias + pm.math.dot(X[holdout_idx], gamma), sd, observed=d)
# posterior predictive bias for every campaign (non-centred)
z = pm.Normal("z", 0, 1, shape=C)
xi = pm.Deterministic("xi", mu_bias + pm.math.dot(X, gamma) + tau_xi*z)
# bias-corrected effect for non-holdout campaigns: observational estimate minus predicted bias
pm.Deterministic("tau_corrected", tau_o - xi)
idata = pm.sample(2000, tune=2000, chains=4, target_accept=0.95, random_seed=0)
return m, idataCaveat: z for holdout campaigns is also informed by the likelihood only through the marginal model; for those campaigns, use the closed-form posterior mean above (or add the joint likelihood in non-centred form). Check the prior-predictive of the bias against known experiments before fitting.
Examples
Numbers: three holdouts, five campaigns
Observational SEs 0.01, holdout SEs 0.04, estimated , (average bias ). The weight moved toward the observational estimate is i.e. . So a holdout showing 0.10 lift and an observational estimate of 0.14 combine (after removing the average bias, so 0.12) to . For a campaign with no holdout and observational estimate 0.14, the bias-corrected prediction is with SD . (Illustrative numbers.)
Connections
- Equivalent in spirit to the lift-calibration of MMM priors with experiments in Bayesian Estimation and Priors for MMM; hierarchy and partial pooling: Hierarchical Models, Partial Pooling as Multiple Comparisons Correction.
- Bias as the object to be estimated, instead of postulated: contrast with Franks 2019 - Calibrating Sensitivity Parameters and Cinelli Hazlett 2020 - Planted Confounders and Bayesian Sketch.
- Prior predictive checks for the bias: Prior Predictive Checking; when the answer depends on an unidentified quantity: Unidentified Parameters - Partial Identification and Bayesian Updating.
See Also
Rosenman 2020 - Combining Observational and Experimental Datasets - Overview