Getting a Non-Implemented Error with Laplace Distribution

Hello,

I’m following a time series tutorial from Hierarchical Time Series With Prophet and PyMC3 by Matthijs Brouns - YouTube and keep getting an error with the Laplace distribution.

The error is below:

---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
/tmp/ipykernel_2309/1529980733.py in <module>
      5     delta = pm.Laplace('delta', 0, 0.01, shape = n_changepoints)
      6 
----> 7     growth = k + at.dot(A, delta)
      8     offset = m + at.dog(A, -s * delta)
      9     trend = growth * t + offset

/opt/conda/lib/python3.7/site-packages/aesara/tensor/math.py in dot(l, r)
   2024 
   2025     if not isinstance(r, Variable):
-> 2026         r = as_tensor_variable(r)
   2027 
   2028     try:

/opt/conda/lib/python3.7/site-packages/aesara/tensor/__init__.py in as_tensor_variable(x, name, ndim, **kwargs)
     40 
     41     """
---> 42     return _as_tensor_variable(x, name, ndim, **kwargs)
     43 
     44 

/opt/conda/lib/python3.7/functools.py in wrapper(*args, **kw)
    838                             '1 positional argument')
    839 
--> 840         return dispatch(args[0].__class__)(*args, **kw)
    841 
    842     funcname = getattr(func, '__name__', 'singledispatch function')

/opt/conda/lib/python3.7/site-packages/aesara/tensor/__init__.py in _as_tensor_variable(x, name, ndim, **kwargs)
     47     x, name: Optional[str], ndim: Optional[int], **kwargs
     48 ) -> "TensorVariable":
---> 49     raise NotImplementedError(f"Cannot convert {x} to a tensor variable.")
     50 
     51 

NotImplementedError: Cannot convert delta ~ Laplace to a tensor variable.

I’m not sure if this is an issue with my code or aesara.

Here is the model:

import pymc3 as pm
import aesara
from aesara import tensor as at
import arviz

#define hyper-parameters

#potential number of changes in trends over time
n_changepoints = 5

#make the t
t = np.arange(len(experimental))/len(experimental)
#make the changepoints
s = np.linspace(0, max(t), n_changepoints + 2)[1: -1]

#indicator matrix
A = (t[:, None]>s) * 1

with pm.Model() as model:
    
    k = pm.Normal('k', 0, 1)
    m = pm.Normal('m', 0, 5)
    delta = pm.Laplace('delta', 0, 0.01, shape = n_changepoints)
    
    growth = k + at.dot(A, delta)
    offset = m + at.dot(A, -s * delta)
    trend = growth * t + offset
    
    error = pm.HalfCauchy('sigma', 0.5)
    
    mu_ = trend + error
    
    pm.Poisson("predicted_sales", mu = mu_, observed = experimental['eaches'])
    
    trace = pm.sampling_jax.sample_numpyro_nuts(tune=1000, cores=4, chains = 4)


Is there anything glaringly wrong with the code?

It looks like you are mixing PyMC3 and Aesara, which I don’t think is recommended. Try importing PyMC instead.

1 Like

You actually solved this issue. I will repost the new error message.

A note on the jax sampler, you need to do a separate import: import pymc.sampling_jax, then you will be able to do:

 trace = pymc.sampling_jax.sample_numpyro_nuts(tune=1000, chains = 4)

Note that it’s pymc.sampling_jax, not pm.sampling_jax

I tested it on a Colab following the instructions you linked and everything went fine.

That started then yielded:

/opt/conda/lib/python3.7/site-packages/pymc/aesaraf.py:1010: UserWarning: The parameter 'updates' of aesara.function() expects an OrderedDict, got <class 'dict'>. Using a standard dictionary here results in non-deterministic behavior. You should use an OrderedDict if you are using Python 2.7 (collections.OrderedDict for older python), or use a list of (shared, update) pairs. Do not just convert your dictionary to this type before the call as the conversion will still be non-deterministic.
  **kwargs,
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
/tmp/ipykernel_2309/3434926538.py in <module>
     15     pm.Poisson("predicted_sales", mu = mu_, observed = experimental['7_do'])
     16 
---> 17     trace = pymc.sampling_jax.sample_numpyro_nuts(tune=1000, chains = 4)

/opt/conda/lib/python3.7/site-packages/pymc/sampling_jax.py in sample_numpyro_nuts(draws, tune, chains, target_accept, random_seed, initvals, model, var_names, progress_bar, keep_untransformed, chain_method, idata_kwargs, nuts_kwargs)
    472     )
    473 
--> 474     logp_fn = get_jaxified_logp(model, negative_logp=False)
    475 
    476     if nuts_kwargs is None:

/opt/conda/lib/python3.7/site-packages/pymc/sampling_jax.py in get_jaxified_logp(model, negative_logp)
    104     if not negative_logp:
    105         model_logpt = -model_logpt
--> 106     logp_fn = get_jaxified_graph(inputs=model.value_vars, outputs=[model_logpt])
    107 
    108     def logp_fn_wrap(x):

/opt/conda/lib/python3.7/site-packages/pymc/sampling_jax.py in get_jaxified_graph(inputs, outputs)
     97 
     98     # We now jaxify the optimized fgraph
---> 99     return jax_funcify(fgraph)
    100 
    101 

/opt/conda/lib/python3.7/functools.py in wrapper(*args, **kw)
    838                             '1 positional argument')
    839 
--> 840         return dispatch(args[0].__class__)(*args, **kw)
    841 
    842     funcname = getattr(func, '__name__', 'singledispatch function')

/opt/conda/lib/python3.7/site-packages/aesara/link/jax/dispatch.py in jax_funcify_FunctionGraph(fgraph, node, fgraph_name, **kwargs)
    660         type_conversion_fn=jax_typify,
    661         fgraph_name=fgraph_name,
--> 662         **kwargs,
    663     )
    664 

/opt/conda/lib/python3.7/site-packages/aesara/link/utils.py in fgraph_to_python(fgraph, op_conversion_fn, type_conversion_fn, order, input_storage, output_storage, storage_map, fgraph_name, global_env, local_env, get_name_for_object, squeeze_output, **kwargs)
    744     for node in order:
    745         compiled_func = op_conversion_fn(
--> 746             node.op, node=node, storage_map=storage_map, **kwargs
    747         )
    748 

/opt/conda/lib/python3.7/functools.py in wrapper(*args, **kw)
    838                             '1 positional argument')
    839 
--> 840         return dispatch(args[0].__class__)(*args, **kw)
    841 
    842     funcname = getattr(func, '__name__', 'singledispatch function')

/opt/conda/lib/python3.7/site-packages/aesara/link/jax/dispatch.py in jax_funcify(op, node, storage_map, **kwargs)
    142 def jax_funcify(op, node=None, storage_map=None, **kwargs):
    143     """Create a JAX compatible function from an Aesara `Op`."""
--> 144     raise NotImplementedError(f"No JAX conversion for the given `Op`: {op}")
    145 
    146 

NotImplementedError: No JAX conversion for the given `Op`: BroadcastTo

Strange, I can copy/paste your code and it samples fine. The only thing I changed was to generate fake data, experimental = stats.poisson(1.0).rvs(100). Check that your data type/shape is ok?

That fact that “BroadcastTo” is popping up makes me wonder if the data is a different shape than the mu_ vector.

1 Like

I don’t see a ‘solution’ check but that was it. My observed was a float and needed to be an int.

Hopefully this is the last question for today :slight_smile:

Using your method, I tried the following to get posterior predictive:

with model:
    pm.sample_posterior_predictive(trace, var_names = 'predicted_sales')

But this gives me the following error:

KeyError                                  Traceback (most recent call last)
/opt/conda/lib/python3.7/site-packages/pymc/model.py in __getitem__(self, key)
   1499             try:
-> 1500                 return self.named_vars[self.name_for(key)]
   1501             except KeyError:

KeyError: 'p'

During handling of the above exception, another exception occurred:

KeyError                                  Traceback (most recent call last)
/tmp/ipykernel_16737/1151492224.py in <module>
      1 with model:
----> 2     pm.sample_posterior_predictive(trace, var_names = ('predicted_sales'))

/opt/conda/lib/python3.7/site-packages/pymc/sampling.py in sample_posterior_predictive(trace, samples, model, var_names, size, keep_size, random_seed, progressbar, mode, return_inferencedata, extend_inferencedata, predictions, idata_kwargs)
   1684 
   1685     if var_names is not None:
-> 1686         vars_ = [model[x] for x in var_names]
   1687     else:
   1688         vars_ = model.observed_RVs + model.auto_deterministics

/opt/conda/lib/python3.7/site-packages/pymc/sampling.py in <listcomp>(.0)
   1684 
   1685     if var_names is not None:
-> 1686         vars_ = [model[x] for x in var_names]
   1687     else:
   1688         vars_ = model.observed_RVs + model.auto_deterministics

/opt/conda/lib/python3.7/site-packages/pymc/model.py in __getitem__(self, key)
   1500                 return self.named_vars[self.name_for(key)]
   1501             except KeyError:
-> 1502                 raise e
   1503 
   1504     def compile_fn(

/opt/conda/lib/python3.7/site-packages/pymc/model.py in __getitem__(self, key)
   1495     def __getitem__(self, key):
   1496         try:
-> 1497             return self.named_vars[key]
   1498         except KeyError as e:
   1499             try:

KeyError: 'p'

When I take var_names out, PyMC samples then gives the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_16737/1535627613.py in <module>
      1 with model:
----> 2     pm.sample_posterior_predictive(trace)

/opt/conda/lib/python3.7/site-packages/pymc/sampling.py in sample_posterior_predictive(trace, samples, model, var_names, size, keep_size, random_seed, progressbar, mode, return_inferencedata, extend_inferencedata, predictions, idata_kwargs)
   1793     converter.nchains = nchain
   1794     converter.ndraws = len_trace
-> 1795     idata_pp = converter.to_inference_data()
   1796     if extend_inferencedata:
   1797         trace.extend(idata_pp)

/opt/conda/lib/python3.7/site-packages/pymc/backends/arviz.py in to_inference_data(self)
    522             "predictions": self.predictions_to_xarray(),
    523             **self.priors_to_xarray(),
--> 524             "observed_data": self.observed_data_to_xarray(),
    525         }
    526         if self.predictions:

/opt/conda/lib/python3.7/site-packages/arviz/data/base.py in wrapped(cls, *args, **kwargs)
     44                 if all([getattr(cls, prop_i) is None for prop_i in prop]):
     45                     return None
---> 46             return func(cls, *args, **kwargs)
     47 
     48         return wrapped

/opt/conda/lib/python3.7/site-packages/arviz/data/base.py in wrapped(cls, *args, **kwargs)
     44                 if all([getattr(cls, prop_i) is None for prop_i in prop]):
     45                     return None
---> 46             return func(cls, *args, **kwargs)
     47 
     48         return wrapped

/opt/conda/lib/python3.7/site-packages/pymc/backends/arviz.py in observed_data_to_xarray(self)
    458             coords=self.coords,
    459             dims=self.dims,
--> 460             default_dims=[],
    461         )
    462 

TypeError: dict_to_dataset() got an unexpected keyword argument 'default_dims'