I’m trying to translate examples in “Bayesian methods for hackers” into pyMC v5. Actually it is really painful since many documents from google are mixed with v2, v3, v4. Even I have read the migration guide of v4, there’s still a lot I don’t understand.
To be specific, in the SMS frequency example, how can I construct lambda_
that involves array index manipulation?
lambda_1 = pm.Exponential("lambda_1", alpha)
lambda_2 = pm.Exponential("lambda_2", alpha)
tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data)
@pm.deterministic
def lambda_(tau=tau, lambda_1=lambda_1, lambda_2=lambda_2):
out = np.zeros(n_count_data)
out[:tau] = lambda_1 # lambda before tau is lambda1
out[tau:] = lambda_2 # lambda after tau is lambda2
return out
observation = pm.Poisson("obs", lambda_, value=count_data, observed=True)
model = pm.Model([observation, lambda_1, lambda_2, tau])
I tried the following:
def mixed_lambda(lambda1=lambda1, lambda2=lambda2, tau=tau):
out = np.zeros(len(real_pv))
t = tau.eval()
out[:t] = lambda1.eval()
out[t:] = lambda2.eval()
return out
with model:
mixed_lambda = pm.Deterministic("mixed_lambda", mixed_lambda())
However pyMC blames incompatible between np.array
and aesara.tensor
. Could you tell me the right way to do it? Any related tip and best practice are welcome. Thank you in advance.
The book has an official PyMC3 version: GitHub - CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers: aka "Bayesian Methods for Hackers": An introduction to Bayesian methods + probabilistic programming with a computation/understanding-first, mathematics-second point of view. All in pure Python ;)
That API should be much more similar to V4/V5.
In general you can write complex deterministics just like you would write Numpy (replacing np
by pt
or at
), except for some special operations like branching, looping and writing to arrays (as you are doing with indexing). Writing to arrays is supported via set_subtensor
, but it’s probably easier to use where
which works just like in numpy.
You should not use eval
. That’s for debugging only, as it tries to evaluate the expression you have. You should always give PyMC an unevaluated expression.
import pytensor.tensor as pt
with pm.Model() as m:
lambda_1 = pm.Exponential("lambda_1", alpha)
lambda_2 = pm.Exponential("lambda_2", alpha)
tau = pm.DiscreteUniform("tau", lower=0, upper=n_count_data)
lambda_ = pt.where(tau <= pt.arange(len(count_data)), lambda_1, lambda_2)
observation = pm.Poisson("obs", lambda_, observed=count_data)
1 Like
Thank you for the reply, it works! pt.where
and .eval
concepts helps me a lot.
However, when I change pytensor
to aesara
, it blames at tau <= at.arange(len(real_pv))
part for:
NotImplementedError: Cannot convert ARange{dtype='int64'}.0 to a tensor variable.
File ~/pyenv/lib/python3.10/site-packages/pytensor/tensor/var.py:45, in _tensor_py_operators.__le__(self, other)
44 def __le__(self, other):
---> 45 rval = at.math.le(self, other)
46 rval._is_nonzero = False
47 return rval
File ~/pyenv/lib/python3.10/site-packages/pytensor/graph/op.py:296, in Op.__call__(self, *inputs, **kwargs)
254 r"""Construct an `Apply` node using :meth:`Op.make_node` and return its outputs.
255
256 This method is just a wrapper around :meth:`Op.make_node`.
(...)
293
294 """
295 return_list = kwargs.pop("return_list", False)
--> 296 node = self.make_node(*inputs, **kwargs)
298 if config.compute_test_value != "off":
299 compute_test_value(node)
...
It seems the tensor
in pytensor
and aesara
are slightly different. The backend of pyMC changes a lot and really complicated. Why does pyMC mix two or more tensor structure? Is there any preference or idiom about tensor types for daily usage?
You cannot mix Aesara and Pytensor!!!
PyMC 4.x uses Aesara
PyMC 5.x uses PyTensor
Otherwise they work the same (PyTensor is a fork of the Aesara project maintained by the PyMC developers)
1 Like