pymc-examples icon indicating copy to clipboard operation
pymc-examples copied to clipboard

unhashable type: 'dict' in Bayesian regression with truncated or censored data

Open computbiolgeek opened this issue 3 years ago • 5 comments

Bayesian regression with truncated or censored data: Notebook url:

Issue description

Running the following chunk of code in the corresponding notebook

fig, ax = plt.subplots(figsize=(10, 3))

with pm.Model() as m:
    pm.Normal("y", 0, 2)

with pm.Model() as m_censored:
    pm.Censored("y", pm.Normal.dist(0, 2), lower=-1.0, upper=None)

logp_fn = m.logp
logp_censored_fn = m_censored.logp

xi = np.hstack((np.linspace(-6, -1.01), [-1.0], np.linspace(-0.99, 6)))

ax.plot(xi, [np.exp(logp_fn({"y": x})) for x in xi], label="uncensored")
ax.plot(xi, [np.exp(logp_censored_fn({"y": x})) for x in xi], label="censored", lw=8, alpha=0.6)
ax.axvline(-1, c="k", ls="--")
ax.legend()
ax.set(xlabel="$y$", ylabel="probability density", ylim=(-0.02, 0.4));

gave a TypeError

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [60], in <cell line: 14>()
     10 logp_censored_fn = m_censored.logp
     12 xi = np.hstack((np.linspace(-6, -1.01), [-1.0], np.linspace(-0.99, 6)))
---> 14 ax.plot(xi, [np.exp(logp_fn({"y": x})) for x in xi], label="uncensored")
     15 ax.plot(xi, [np.exp(logp_censored_fn({"y": x})) for x in xi], label="censored", lw=8, alpha=0.6)
     16 ax.axvline(-1, c="k", ls="--")

Input In [60], in <listcomp>(.0)
     10 logp_censored_fn = m_censored.logp
     12 xi = np.hstack((np.linspace(-6, -1.01), [-1.0], np.linspace(-0.99, 6)))
---> 14 ax.plot(xi, [np.exp(logp_fn({"y": x})) for x in xi], label="uncensored")
     15 ax.plot(xi, [np.exp(logp_censored_fn({"y": x})) for x in xi], label="censored", lw=8, alpha=0.6)
     16 ax.axvline(-1, c="k", ls="--")

File /opt/homebrew/lib/python3.9/site-packages/pymc/model.py:742, in Model.logp(self, vars, jacobian, sum)
    740 rv_order, potential_order = [], []
    741 for i, var in enumerate(varlist):
--> 742     value_var = self.rvs_to_values.get(var)
    743     if value_var is not None:
    744         rv_values[var] = value_var

TypeError: unhashable type: 'dict'

Expected output

The figure below the above chunk of code, as shown in the notebook.

Proposed solution

No solution yet. Looked the signature of m.logp, which suggests that a list should be passed as an argument, but had no idea how to achieve that.

computbiolgeek avatar Jul 15 '22 20:07 computbiolgeek

Thanks for reporting. What versions of pymc and aesara are you using?

OriolAbril avatar Jul 23 '22 14:07 OriolAbril

Thanks for the reply. My PyMC and aesara version are

pymc                          4.1.3
aesara                        2.7.7

computbiolgeek avatar Jul 28 '22 16:07 computbiolgeek

Instead of m_censored.logp you should call m_censored.compile_logp()

ricardoV94 avatar Jul 28 '22 17:07 ricardoV94

Do you want to send a PR to update and rerun the notebook @computbiolgeek?

OriolAbril avatar Jul 28 '22 17:07 OriolAbril

Changing

logp_fn = m.logp
logp_censored_fn = m_censored.logp

to

logp_fn = m.compile_logp()
logp_censored_fn = m_censored.compile_logp()

did resolve the error. Thank you so much!

I typed up everything from scratch and did not clone the notebook. Let me know if a PR is still needed. Thanks!

computbiolgeek avatar Jul 28 '22 20:07 computbiolgeek

I confirm the code in the notebook still needs to be updated

ricardoV94 avatar Sep 14 '22 10:09 ricardoV94