New on this discourse I have searched for similar questions but couldn’t find one (apologies if I overlooked something).
My problem is the following (also described in somewhat more detail here. I have a linear function, that I would like to recover, but the “noise” on the data is exponential: only going upwards from the regression line I am after:
The red line is the line to be recovered.
Usually (read: with e.g. a Normal likelihood) I can do something like
with pm.Model() as linreg: sigma = pm.HalfCauchy('sigma', beta=10, testval=1.) intercept = pm.Normal('Intercept', 0, sigma=20) x_coeff = pm.Normal('Slope', 0, sigma=20) likelihood = pm.Normal('y', mu=intercept + x_coeff * x, sigma=sigma, observed=y) trace = pm.sample()
This works, because the Normal distribution has a location parameter (the mean, mu). The Exponential does not have a location parameter, it is always at 0. I need it to be away from that, on the regression line I am trying to find.
I have solved it in a bit of a hacky way:
class shiftedExp(pm.Exponential): def __init__(self, lam=1., shift=0, *args, **kwargs): super().__init__(lam=lam, *args, **kwargs) self.lam = lam self.shift = shift def logp(self, value): return super().logp(value-self.shift)
And then I use the shiftedExp as my likelihood. As far as I can tell this works nicely, but I was wondering:
- Did I overlook a built-in way of doing this?
- Is this acceptable/recommended?
- Would it be worth having an optional shift (or
loc, in more scipy-like lingo) parameter in the definition on the Exponential distribution. I think the changes in the code can be fairly trivial. If this sounds worthwhile to people, I’d be up to give it a try, but I would likely need some guidance, as it would be my first contribution…