How to implement Beta Function effectively in Pymc3

Thank you for the reply! I will try using the theano gamma function. I’ve now made my beta_func into

def beta_func(a, b):
  return tt.gamma(a) * tt.gamma(b) / tt.gamma(a+b)

and I then changed my ln_prob_vec to be a list and then converting to a tt.vector:

# Find the probability of churn for all values prior
        ln_prob_vec = []
        for i in range(1, n_obs + 1):
            ln_prob_vec.append(beta_func(alpha + 1, beta + i - 1)/beta_func(alpha, beta))
        ln_prob_vec = np.log(ln_prob_vec)
        ln_prob_vec = tt.vector('ln_prob_vec')

The “good” news is that I am now getting a different error but don’t know what it means:


TestValueErrorTraceback (most recent call last)
/usr/local/lib/python3.8/site-packages/theano/graph/op.py in compute_test_value(node)
     80         try:
---> 81             storage_map[ins] = [ins.get_test_value()]
     82             compute_map[ins] = [True]

/usr/local/lib/python3.8/site-packages/theano/graph/basic.py in get_test_value(self)
    421             detailed_err_msg = get_variable_trace_string(self)
--> 422             raise TestValueError(f"{self} has no test value {detailed_err_msg}")
    423 

TestValueError: ln_prob_vec has no test value  
Backtrace when that variable is created:

  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3169, in run_cell_async
    has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3361, in run_ast_nodes
    if (await self.run_code(code, result,  async_=asy)):
  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3441, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-107-bb6869c0d6ad>", line 23, in <module>
    likelihood = pm.DensityDist('likelihood', logp, observed = {'survived': survived, 'churned': churned})
  File "/usr/local/lib/python3.8/site-packages/pymc3/distributions/distribution.py", line 122, in __new__
    return model.Var(name, dist, data, total_size, dims=dims)
  File "/usr/local/lib/python3.8/site-packages/pymc3/model.py", line 1162, in Var
    var = MultiObservedRV(
  File "/usr/local/lib/python3.8/site-packages/pymc3/model.py", line 1873, in __init__
    self.logp_elemwiset = distribution.logp(**self.data)
  File "<ipython-input-107-bb6869c0d6ad>", line 19, in logp
    ln_prob_vec = tt.vector('ln_prob_vec')


During handling of the above exception, another exception occurred:

ValueErrorTraceback (most recent call last)
<ipython-input-107-bb6869c0d6ad> in <module>
     21         return pm.math.dot(churned, ln_prob_vec) + survived[-1] * ln_surv_prob
     22 
---> 23     likelihood = pm.DensityDist('likelihood', logp, observed = {'survived': survived, 'churned': churned})
     24     sbg_trace = pm.sample(200) # just a sanity check to see if it even runs...

/usr/local/lib/python3.8/site-packages/pymc3/distributions/distribution.py in __new__(cls, name, *args, **kwargs)
    120         else:
    121             dist = cls.dist(*args, **kwargs)
--> 122         return model.Var(name, dist, data, total_size, dims=dims)
    123 
    124     def __getnewargs__(self):

/usr/local/lib/python3.8/site-packages/pymc3/model.py in Var(self, name, dist, data, total_size, dims)
   1160         elif isinstance(data, dict):
   1161             with self:
-> 1162                 var = MultiObservedRV(
   1163                     name=name,
   1164                     data=data,

/usr/local/lib/python3.8/site-packages/pymc3/model.py in __init__(self, name, data, distribution, total_size, model)
   1871             datum.missing_values for datum in self.data.values() if datum.missing_values is not None
   1872         ]
-> 1873         self.logp_elemwiset = distribution.logp(**self.data)
   1874         # The logp might need scaling in minibatches.
   1875         # This is done in `Factor`.

<ipython-input-107-bb6869c0d6ad> in logp(survived, churned, alpha, beta)
     19         ln_prob_vec = tt.vector('ln_prob_vec')
     20 
---> 21         return pm.math.dot(churned, ln_prob_vec) + survived[-1] * ln_surv_prob
     22 
     23     likelihood = pm.DensityDist('likelihood', logp, observed = {'survived': survived, 'churned': churned})

/usr/local/lib/python3.8/site-packages/theano/tensor/basic.py in dot(l, r)
   6166 
   6167     try:
-> 6168         res = l.__dot__(r)
   6169         if res is NotImplemented:
   6170             raise NotImplementedError

/usr/local/lib/python3.8/site-packages/theano/tensor/var.py in __dot__(left, right)
    661 
    662     def __dot__(left, right):
--> 663         return theano.tensor.basic.dense_dot(left, right)
    664 
    665     def __rdot__(right, left):

/usr/local/lib/python3.8/site-packages/theano/tensor/basic.py in dense_dot(a, b)
   6221         return tensordot(a, b, [[a.ndim - 1], [np.maximum(0, b.ndim - 2)]])
   6222     else:
-> 6223         return _dot(a, b)
   6224 
   6225 

/usr/local/lib/python3.8/site-packages/theano/graph/op.py in __call__(self, *inputs, **kwargs)
    251 
    252         if config.compute_test_value != "off":
--> 253             compute_test_value(node)
    254 
    255         if self.default_output is not None:

/usr/local/lib/python3.8/site-packages/theano/graph/op.py in compute_test_value(node)
     92                 detailed_err_msg = get_variable_trace_string(ins)
     93 
---> 94                 raise ValueError(
     95                     f"Cannot compute test value: input {i} ({ins}) of Op {node} missing default value. {detailed_err_msg}"
     96                 )

ValueError: Cannot compute test value: input 1 (ln_prob_vec) of Op dot(TensorConstant{[131. 126... 34.  26.]}, ln_prob_vec) missing default value.  
Backtrace when that variable is created:

  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3169, in run_cell_async
    has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3361, in run_ast_nodes
    if (await self.run_code(code, result,  async_=asy)):
  File "/usr/local/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3441, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-107-bb6869c0d6ad>", line 23, in <module>
    likelihood = pm.DensityDist('likelihood', logp, observed = {'survived': survived, 'churned': churned})
  File "/usr/local/lib/python3.8/site-packages/pymc3/distributions/distribution.py", line 122, in __new__
    return model.Var(name, dist, data, total_size, dims=dims)
  File "/usr/local/lib/python3.8/site-packages/pymc3/model.py", line 1162, in Var
    var = MultiObservedRV(
  File "/usr/local/lib/python3.8/site-packages/pymc3/model.py", line 1873, in __init__
    self.logp_elemwiset = distribution.logp(**self.data)
  File "<ipython-input-107-bb6869c0d6ad>", line 19, in logp
    ln_prob_vec = tt.vector('ln_prob_vec')

Is it not liking that I am trying to take the dot product of a theano vector and a numpy array?