I am trying to expand the model in the page
by adding a log normal noise to the Binomial distribution. I feel like this might be problematic as I am adding a continous RV to a discrete one. Nevertheless, I tried some of the most straight forward approaches which seem to produce only partially sensical results. The way I modify the generated data is as follows:
# Generate data
y = rng.binomial(n, p_true)
# This is the extra step
y =np.round(rng.lognormal(np.log(y), 0.2, size=y.size))
I believe that the question I have at hand can be modelled with something similar to this and this is why I am trying this. The full code for data generation and modelling is below (the model is a modified version of what is in the page above):
import numpy as np
import pymc3 as pm
import arviz as az
import pandas as pd
from scipy.special import expit
rng = np.random.default_rng(1234)
# true params
β0_true = 0.7
β1_true = 0.4
# number of yes/no questions
n = 20
sample_size = 30
x = np.linspace(-10, 20, sample_size)
# Linear model
μ_true = β0_true + β1_true * x
# transformation (inverse logit function = expit)
p_true = expit(ÎĽ_true)
# Generate data
y = rng.binomial(n, p_true)
y = np.round(y*rng.lognormal(0,0.2,size=y.size))
# bundle data into dataframe
data = pd.DataFrame({"x": x, "y": y})
coords = {"observation": data.index.values}
with pm.Model(coords=coords) as binomial_regression_model:
# priors
β0 = pm.Normal("β0", mu=0, sigma=1)
β1 = pm.Normal("β1", mu=0, sigma=1)
sd = pm.Exponential("sd", 1)
# linear model
μ = β0 + β1 * data["x"]
p = pm.Deterministic("p", pm.math.invlogit(ÎĽ))
# likelihood
yb = pm.Binomial("yb", n=n, p=p, shape=sample_size)
pm.Normal("obs", pm.math.log(yb+0.001), sd, observed=pm.math.log(data["y"]+0.001).T,
shape=sample_size)
with binomial_regression_model:
trace = pm.sample(5000, tune=10000, return_inferencedata=True,
nuts={'target_accept':0.95}, chains=6,cores=6)
az.plot_trace(trace, var_names=["β0", "β1", "sd"])
summary = az.summary(trace, var_names=["β0", "β1", "sd"])
It seems to get a good estimate on sd and B1 but B0 is close to 0 (and convergence is problematic too). Obviously letting go off the normal term and trying to put observed into the Binomial would be a bit problematic too since I would need to modify n to be the maximum of y which could be quite high compared to the real value. I am not always in the domain where normal approximation to the binomial is valid (which would be more natural to use here if it were). Another interesting observation is that if I increase sample_size to say 300 both B0 and B1 come out as 0 and sd comes out as 2 (here there are no problems in convergence and estimates have very narrow HDIs). Am I trying to something non-sensical here? Thanks