Hi all,
This is my first time posting here, so please forgive me, if the editing is off…
I think I need some help with either re-parametrizing my model or otherwise better understanding sampling, as right now my chains fail to converge.
My model is like this:
or in code:
# Data: 500 parts with 10 failures
nparts = 500
nfail = 10
# observed failures (only sum will be important but I want the coordinates)
y = np.concatenate((np.repeat(1,nfail), np.repeat(0,nparts - nfail)))
# bundle data into dataframe
data = pd.DataFrame({"y": y})
coords = {"parts": data.index.values}
with pm.Model(coords=coords) as stress_distribution_model:
# priors, further re-parametrization necessary...
sigma_stress = pm.TruncatedNormal("sigma_stress", mu=1, sigma=2, lower=0.001, upper=10)
q90_stress = pm.TruncatedNormal("q90_stress", mu=1, sigma=2, lower=0.1, upper=2)
mu_stress = pm.Deterministic("mu_stress", np.log(q90_stress) - 1.64*sigma_stress)
# lognormal stress distribution
stress = pm.LogNormal("stress", mu = mu_stress, sigma = sigma_stress, dims="parts")
# pfailure is given by invlogit
x = -5 + 4 * stress
pfailure = pm.Deterministic("pfailure", pm.math.invlogit(x), dims="parts")
# likelihood
failure = pm.Bernoulli("failure", p=pfailure, dims="parts")
nfailure = pm.Deterministic("nfailure", pm.math.sum(failure))
# observe only number of failures, not individual parts
# pm.Potential and pm.DiracDelta do not accept "observed" parameter
# therefore use normal distribution with small sigma (nfailure is actually discrete)
pm.Normal("observed", mu = nfailure, sigma = 0.001, observed = nfail)
I already did some re-parametrization using q90_stress instead of mu_stress as top-level variable and before sampling was even worse. My priors look like this
and posteriors like this
Inspection of the traces and energy plots clearly shows lack of convergence:
Is there a way to cleverly re-parametrize my model to improve sampling? Or should I change how the sampler does things? Currently I’m running the sampler pretty much with default settings and it chooses to do
CompoundStep
>NUTS: [sigma_stress, q90_stress, stress]
>BinaryGibbsMetropolis: [failure]
If (instead of using pymc) I implement a dumb “shotgun” method to draw 10000 samples from the prior distribution and compute the likelihood myself I get posteriors like this