Simoiu 2017 - Threshold Test Generative Model

Summary

Each stop of a race- driver by department draws a signal , a search occurs iff , and a hit occurs with probability . Search and hit counts are binomial with probabilities and . Identification comes from additive race and department structure on plus hierarchical priors on thresholds.

Overview

Observed per stop: race , department , search , hit . Goal: race-specific thresholds per department. Bayesian benefits: uncertainty without bootstrapping, and pooling across departments for rarely stopped groups.

Main Content

Generative process (Sec. 2.3)

Signal: with mean and total count (i.e. , ). Search: iff . Hit: if , else . Structure (Eqs. 1-2): , , with for the largest department. This gives parameters for signal distributions.

Priors

; , , ; likewise; thresholds with , per race. is half-normal. Two SDs of on span roughly a 2%-98% chance of contraband; the same range holds for thresholds; can differ across departments by a factor of about 50. Results hold with priors (slower).

Sufficient statistics and exact likelihood (Eq. 3)

Aggregate , , with stops fixed. Then

with the beta CDF in mean/count parametrisation and . The likelihood thus has binomial terms, independent of the number of stops.

Proof. , and , giving , whose first argument pair in mean/count form is .

Parameter counting (why the model is identified)

Per race-department pair there are three unknowns but only two observed rates (search, hit), so unknowns face data. The additive structure reduces the total to , which is when and . Hierarchical priors add regularisation. (Identification is by structure plus priors, not by data alone; see Simoiu 2017 - Limitations Extensions and Identification Ridge.)

Examples

Checking Eq. 3 numerically

With the formula gives ; direct conditional expectation of a above 0.2 gives as well. Interpretation: the closed form is exact, so no simulation of individual stops is needed.

from scipy import stats
phi, lam, t = 0.3, 25, 0.2
a, b = phi*lam, (1-phi)*lam
q = phi * (1 - stats.beta(a+1, b).cdf(t)) / (1 - stats.beta(a, b).cdf(t))

PyMC-style sketch (untested).

with pm.Model():
    phi_r = pm.Normal("phi_r", 0, 2, shape=R); lam_r = pm.Normal("lam_r", 0, 2, shape=R)
    mu_t = pm.Normal("mu_t", 0, 2, shape=R); sd_t = pm.HalfNormal("sd_t", 2, shape=R)
    t = pm.math.invlogit(pm.Normal("t_raw", mu_t[:,None], sd_t[:,None], shape=(R, D)))
    phi = pm.math.invlogit(phi_r[:,None] + phi_d[None,:]); lam = pm.math.exp(lam_r[:,None] + lam_d[None,:])
    # beta CDF via pt.betainc(a, b, x): p = 1 - betainc(phi*lam, (1-phi)*lam, t)
    pm.Binomial("S", n, p, observed=S); pm.Binomial("H", S, q, observed=H)

Connections

Hierarchical Models (shrinkage of toward race means), Efficient MCMC (the paper samples with Stan NUTS, 5 chains of 2,500 warm-up + 2,500 draws, ), a related fast variant by Pierson et al. (2017) is cited.

See Also

Simoiu 2017 - Infra-Marginality and the Threshold Test - Overview