You could if you created also a custom likelihood function. But only if you really needed it. This will be easier once we support censored responses natively in Bambi (which should happen soon).
See the example
from functools import partial
from bambi.families.univariate import UnivariateFamily
def CensoredZeroInflatedBinomial(name, psi, n, p, lower, upper, observed):
dist = pm.ZeroInflatedBinomial.dist(psi=psi, n=n, p=p)
return pm.Censored(name, dist, lower=lower, upper=upper, observed=observed)
dist_fn = partial(CensoredZeroInflatedBinomial, lower=0, upper=10)
class ZeroInflatedBinomial(UnivariateFamily):
SUPPORTED_LINKS = {
"p": ["identity", "logit", "probit", "cloglog"],
"psi": ["logit", "probit", "cloglog"]
}
@staticmethod
def transform_backend_kwargs(kwargs):
observed = kwargs.pop("observed")
kwargs["observed"] = observed[:, 0].squeeze()
kwargs["n"] = observed[:, 1].squeeze()
return kwargs
likelihood = bmb.Likelihood("CensoredZeroInflatedBinomial", params=["p", "psi"], parent="p", dist=dist_fn)
links = {"p": "logit", "psi": "logit"}
zinb_family = ZeroInflatedBinomial("zinb", likelihood, links)
zinb_family
See the usage of the custom likelihood function, which is passed to the dist
argument in bmb.Likelihood
. The limitation is that lower and upper can’t be taken from the dataset, they have to be fixed to some values. If you want to make them equal to arrays instead of scalars, you can try fixing them to data["lower"]
and data["upper"]
.
But again, if you don’t really need this, don’t do it because it’s kind of a Frankenstein and only works because I know how you can inject things in the right places to make things work. This will be much better when we support it natively.