Hi all,
I’m trying to learn the latest version of pytensor/pymc by implementing the Event-Based Model (Event Based Model — Disease Progression Modelling) in it. It’s a straightforward generative process. But I’ve been finding it a bit tricky as it involves estimating a permutation.
First, here’s a summary of the data:
synth_data = pd.read_csv('./data/synthetic_400_3.csv')
synth_data_np = synth_data.to_numpy()
K = synth_data_np.shape[1] -1
N=synth_data_np.shape[0]
synth_data.shape```
(400, 4)```
The data are 400 data points with three features and the last dimension is a binary class label.
Here’s the model definition code (which runs fine).
my_mod = pm.Model()
with my_mod:
musd = pm.Normal.dist( mu=np.array([0., 0., 0.]), sigma=np.array([1, 1, 1]))
sigsd = pm.HalfNormal.dist( sigma=np.array([2., 2., 2.]))
musc = pm.Normal.dist(mu=np.array([-1., -1., -1]), sigma=np.array([1,1,1]))
sigsc = pm.HalfNormal.dist(sigma=np.array([2.,2.,2.]))
S = pt.tensor.random.permutation(x=K, name='S')
for n in np.arange(N):
n_k = pm.DiscreteUniform(f'n{n}_k', lower=0, upper=K-1)
cur_mus = pt.tensor.switch(pt.tensor.ge(S,n_k), musd, musc)
cur_sigs = pt.tensor.switch(pt.tensor.ge(S,n_k), sigsd, sigsc)
if synth_data_np[n,K] == 0:
cur_mus = musc
cur_sigs = sigsc
x = pm.Normal(f'x_{n}', mu=cur_mus, sigma=cur_sigs, observed=synth_data_np[n,0:K])
Here’s the code for sampling and error I get:
with my_mod:
samps = pm.sample()
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[15], line 2 1 with my_mod: ----> 2 samps = pm.sample() File [~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/sampling/mcmc.py:653](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/jausterw/work/playjuly2023/~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/sampling/mcmc.py:653), in sample(draws, tune, chains, cores, random_seed, progressbar, step, nuts_sampler, initvals, init, jitter_max_retries, n_init, trace, discard_tuned_samples, compute_convergence_checks, keep_warning_stat, return_inferencedata, idata_kwargs, nuts_sampler_kwargs, callback, mp_ctx, model, **kwargs) 650 auto_nuts_init = False 652 initial_points = None --> 653 step = assign_step_methods(model, step, methods=pm.STEP_METHODS, step_kwargs=kwargs) 655 if nuts_sampler != "pymc": 656 if not isinstance(step, NUTS): File [~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/sampling/mcmc.py:211](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/jausterw/work/playjuly2023/~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/sampling/mcmc.py:211), in assign_step_methods(model, step, methods, step_kwargs) 209 methods_list: List[Type[BlockedStep]] = list(methods or pm.STEP_METHODS) 210 selected_steps: Dict[Type[BlockedStep], List] = {} --> 211 model_logp = model.logp() 213 for var in model.value_vars: 214 if var not in assigned_vars: 215 # determine if a gradient can be computed File [~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/model.py:764](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/jausterw/work/playjuly2023/~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/model.py:764), in Model.logp(self, vars, jacobian, sum) 762 rv_logps: List[TensorVariable] = [] 763 if rvs: --> 764 rv_logps = transformed_conditional_logp( 765 rvs=rvs, 766 rvs_to_values=self.rvs_to_values, 767 rvs_to_transforms=self.rvs_to_transforms, 768 jacobian=jacobian, 769 ) 770 assert isinstance(rv_logps, list) 772 # Replace random variables by their value variables in potential terms File [~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/logprob/basic.py:385](https://vscode-remote+wsl-002bubuntu.vscode-resource.vscode-cdn.net/home/jausterw/work/playjuly2023/~/miniconda3/envs/pymc_env/lib/python3.11/site-packages/pymc/logprob/basic.py:385), in transformed_conditional_logp(rvs, rvs_to_values, rvs_to_transforms, jacobian, **kwargs) 383 rvs_in_logp_expressions = _find_unallowed_rvs_in_graph(logp_terms_list) 384 if rvs_in_logp_expressions: --> 385 raise ValueError(RVS_IN_JOINT_LOGP_GRAPH_MSG % rvs_in_logp_expressions) 387 return logp_terms_list ValueError: Random variables detected in the logp graph: {S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, S, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, S, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, S, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, halfnormal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out, normal_rv{0, (0, 0), floatX, False}.out,... This can happen when DensityDist logp or Interval transform functions reference nonlocal variables, or when not all rvs have a corresponding value variable.
(Note I cut a bit of the redundant error for space)
Thanks for your time
Joe