0

I am trying to build a Bayesian hierarchical time series model to understand sales data of four stores using PyMC 5.4 in Python. All the stores have a seasonal component, that I am trying to model using a Fourier series. However, for the sake of simplicity, I decided to start with the linear model below and later add the Fourier series (see commented PyMC code below).

The variables I'm using in the linear model are:

  • stores: array([2, 5, 6, 7]). These are the stores names.
  • coords: dictionary = {'fourier_features': array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]), 'stores': array([2, 5, 6, 7])}
  • t: array, with shape (4, 59). Time variable. Four stores, each with 59 monthly time observations
  • y_sales: array, with shape (4, 59). Sales variable. Four stores, each with 59 monthly sales observations

The linear model is as follows:

with pm.Model(check_bounds=False, coords=coords) as partial_pooled_linear:
    # Hyperpriors
    mu_alpha = pm.Normal("mu_alpha", mu=0, sigma=0.5)
    mu_beta = pm.Normal("mu_beta", mu=0, sigma=0.5)
    mu_sigma = pm.HalfNormal("mu_sigma", sigma=0.1)
    #β_fourier = pm.Normal("β_fourier", mu=0, sigma=0.01, dims="fourier_features")
    #seasonality = pm.Deterministic("seasonality", pm.math.dot(β_fourier,
    #              fourier_features.to_numpy().T))

    # Store-level priors
    alpha = pm.Normal("alpha", mu=mu_alpha, sigma=1, dims=("stores",))
    beta = pm.Normal("beta", mu=mu_beta, sigma=1, dims=("stores",))
    sigma = pm.HalfNormal("sigma", sigma=mu_sigma, dims=("stores",))
    
    # Define trend for each store
    trend = pm.Deterministic("trend", alpha + (beta * t).T)
    #mu = pm.Deterministic("mu", alpha[stores] + trend, dims=("stores"))

    # Likelihood for each store
    y = pm.Normal("likelihood", mu=trend, observed=y_sales)

I am getting the following error:



---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/elemwise.py:441, in Elemwise.get_output_info(self, dim_shuffle, *inputs)
    439 try:
    440     out_shapes = [
--> 441         [
    442             get_most_specialized_shape(shape)
    443             for shape in zip(*[inp.type.shape for inp in inputs])
    444         ]
    445     ] * shadow.nout
    446 except ValueError:

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/elemwise.py:442, in (.0)
    439 try:
    440     out_shapes = [
    441         [
--> 442             get_most_specialized_shape(shape)
    443             for shape in zip(*[inp.type.shape for inp in inputs])
    444         ]
    445     ] * shadow.nout
    446 except ValueError:

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/elemwise.py:434, in Elemwise.get_output_info..get_most_specialized_shape(shapes)
    433 if len(shapes) > 1:
--> 434     raise ValueError
    435 return tuple(shapes)[0]

ValueError: 

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
Cell In[66], line 17
     14 sigma = pm.HalfNormal("sigma", sigma=mu_sigma, dims=("stores",))
     16 # Define trend for each store
---> 17 trend = pm.Deterministic("trend", alpha + (beta * t).T)
     18 #mu = pm.Deterministic("mu", alpha[stores] + trend, dims=("stores"))
     19 
     20 # Likelihood for each store
     21 y = pm.Normal("likelihood", mu=trend, observed=y_sales)

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/var.py:133, in _tensor_py_operators.__mul__(self, other)
    129 def __mul__(self, other):
    130     # See explanation in __add__ for the error caught
    131     # and the return value in that case
    132     try:
--> 133         return at.math.mul(self, other)
    134     except (NotImplementedError, TypeError):
    135         return NotImplemented

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/graph/op.py:295, in Op.__call__(self, *inputs, **kwargs)
    253 r"""Construct an `Apply` node using :meth:`Op.make_node` and return its outputs.
    254 
    255 This method is just a wrapper around :meth:`Op.make_node`.
   (...)
    292 
    293 """
    294 return_list = kwargs.pop("return_list", False)
--> 295 node = self.make_node(*inputs, **kwargs)
    297 if config.compute_test_value != "off":
    298     compute_test_value(node)

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/elemwise.py:485, in Elemwise.make_node(self, *inputs)
    479 """
    480 If the inputs have different number of dimensions, their shape
    481 is left-completed to the greatest number of dimensions with 1s
    482 using DimShuffle.
    483 """
    484 inputs = [as_tensor_variable(i) for i in inputs]
--> 485 out_dtypes, out_shapes, inputs = self.get_output_info(DimShuffle, *inputs)
    486 outputs = [
    487     TensorType(dtype=dtype, shape=shape)()
    488     for dtype, shape in zip(out_dtypes, out_shapes)
    489 ]
    490 return Apply(self, inputs, outputs)

File ~/opt/anaconda3/envs/pymc_env/lib/python3.11/site-packages/pytensor/tensor/elemwise.py:447, in Elemwise.get_output_info(self, dim_shuffle, *inputs)
    440     out_shapes = [
    441         [
    442             get_most_specialized_shape(shape)
    443             for shape in zip(*[inp.type.shape for inp in inputs])
    444         ]
    445     ] * shadow.nout
    446 except ValueError:
--> 447     raise ValueError(
    448         f"Incompatible Elemwise input shapes {[inp.type.shape for inp in inputs]}"
    449     )
    451 # inplace_pattern maps output idx -> input idx
    452 inplace_pattern = self.inplace_pattern

ValueError: Incompatible Elemwise input shapes [(1, 4), (4, 59)]
vbrei
  • 1

0 Answers0