Hello! I am new to PyMC and trying to estimate the distribution for some datasets. I have a dataset whose distribution is I believe close to a Moyal distribution, if the Moyal distribution pdf were reflected such that the heavier tail were on the left rather than the right. All data values are positive. If I simply negate the dataset, then its distribution has the right shape for a Moyal distribution but all the values are negative. I have tried simply estimating the parameters of a Moyal distribution on this negated data. Based on the documentation here, the domain of the Moyal pdf is -inf to inf, so I am not sure why I cannot use the negated data, but I get a SamplingError stating that the Logp initial evaluation result for sigma was nan. If instead I negate the data and also shift it so that it is all positive (by adding to each point the maximum of the dataset), I am able to estimate the Moyal parameters well. However, I do not want to shift the data for reasons related to my science use-case (this needs to be applicable to predict future datasets for which we wouldn’t know what the shift should be to make all values positive). Is there a way to use a Moyal distribution whose pdf is reflected in the sense described above to do the sampling? I think it would still be a proper pdf this way, but I don’t know if there is a way to implement this in PyMC. Alternatively, is there a way to estimate the parameters using the shifted distribution and then transform them to match the non-shifted dataset? I hope this question makes sense. Thanks very much in advance!
Edit: since the parameter mu is linearly related to the mean of the distribution, should I be able to recover the parameters for the original distribution by simply shifting subtracting the shift value from the parameter mu?
You can use CustomDist
to define a flipped MoyalDistribution. Something like:
with pm.Model() as m:
def negated_moyal(mu, sigma, size):
return -pm.Moyal.dist(mu, sigma, size=size)
...
y = pm.CustomDist("y", mu, sigma, dist=negated_moyal, observed=...)
Docstrings on CustomDist: CustomDist — PyMC dev documentation
I see, thank you! And then I would be able to use sample() in the same way as with the regular distribution to estimate mu and sigma? ie:
basic_model = pm.Model()
with basic_model:
mu = pm.Uniform("mu", lower = my_min, upper = my_max
sigma = pm.Uniform("sigma", lower = my_min, upper = my_max)
moyal = pm.CustomDist("y", mu, sigma, dist=negated_moyal, observed= my_data)
idata = pm.sample()
Yes, exactly
Thank you!