Fitting Custom Distributions and Likelihoods

I’m working on building a framework to fit custom densities to data in PyMC3.

This is my starting set-up, where I try to do it with a simple Normal. What am I missing ? Does the custom density logp_norm need to be expressed in Theano ? Is there a simple way to use the @as_op decorator ?

def logp_norm(x, μ, σ):
    """Normal distribtuion."""
    return -0.5*np.log(2*np.pi) - np.log(σ) - (x-μ)**2/(2*σ**2)

with pm.Model() as LogoNormo:
    σ = pm.HalfNormal('μ',sd=1)
    μ = pm.Normal('σ', mu = 0, sd=1)

    "Custom Density"
    # Note that by calling the observed here, you declare the likelihood 
    custom_pdf = pm.DensityDist('custom_pdf', logp_norm(obs_y,μ, σ), observed = obs_y)

    trace = pm.sample(2000, chains=3)
    pm.traceplot(trace, ['μ', 'σ']);

Would appreciate some clues.
Thank you!

Your logp_norm should return a callable. Something along the lines of:

def logp_norm(μ, σ):
    """Normal distribtuion."""
    def logp (x):
        return -0.5*np.log(2*np.pi) - np.log(σ) - (x-μ)**2/(2*σ**2)
    return logp


custom_pdf = pm.DensityDist('custom_pdf', logp_norm(μ, σ), observed = obs_y)

1 Like

The answer is slightly different if you are using pymc3 version 3 (not the pre-release of version 4). Could you say which version you’re using, @Juan_Melo

1 Like

I’m currently using pymc3 3.10.0, and Python 3.7.3 on a Jupyter notebook.

Would you suggest installing the pre-release of version 4? I haven’t looked at it.

No, the DensityDist has not been implemented in version 4 yet

Thanks Ricardo, and Luciano! I was able to fit the distribution with the above code.