Hi team,
I am following the “How-to” instruction on pymc-marketing Pareto/NBD, but get the error. Can anyone please help with it? Thank you!
The code:
flat_config = {
"r_prior": {"dist": "HalfFlat", "kwargs": {}},
"alpha_prior": {"dist": "HalfFlat", "kwargs": {}},
"s_prior": {"dist": "HalfFlat", "kwargs": {}},
"beta_prior": {"dist": "HalfFlat", "kwargs": {}},
}
pnbd_pymc = clv.ParetoNBDModel(data=rfm_data, model_config=flat_config)
pnbd_pymc.build_model()
The error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[13], line 11
3 flat_config = {
4 "r_prior": {"dist": "HalfFlat", "kwargs": {}},
5 "alpha_prior": {"dist": "HalfFlat", "kwargs": {}},
6 "s_prior": {"dist": "HalfFlat", "kwargs": {}},
7 "beta_prior": {"dist": "HalfFlat", "kwargs": {}},
8 }
10 pnbd_pymc = clv.ParetoNBDModel(data=rfm_data, model_config=flat_config)
---> 11 pnbd_pymc.build_model()
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc_marketing/clv/models/pareto_nbd.py:313, in ParetoNBDModel.build_model(self)
310 else:
311 beta = self.model.register_rv(beta_scale_prior, name="beta")
--> 313 ParetoNBD(
314 name="recency_frequency",
315 r=r,
316 alpha=alpha,
317 s=s,
318 beta=beta,
319 T=self.data["T"],
320 observed=np.stack(
321 (self.data["recency"], self.data["frequency"]), axis=1
322 ),
323 dims=["customer_id", "obs_var"],
324 )
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc/distributions/distribution.py:536, in Distribution.__new__(cls, name, rng, dims, initval, observed, total_size, transform, default_transform, *args, **kwargs)
533 elif observed is not None:
534 kwargs["shape"] = tuple(observed.shape)
--> 536 rv_out = cls.dist(*args, **kwargs)
538 rv_out = model.register_rv(
539 rv_out,
540 name,
(...)
546 initval=initval,
547 )
549 # add in pretty-printing support
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc_marketing/clv/distributions.py:413, in ParetoNBD.dist(cls, r, alpha, s, beta, T, **kwargs)
411 @classmethod
412 def dist(cls, r, alpha, s, beta, T, **kwargs):
--> 413 return super().dist([r, alpha, s, beta, T], **kwargs)
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc/distributions/distribution.py:618, in Distribution.dist(cls, dist_params, shape, **kwargs)
615 ndim_supp = cls.rv_op(*dist_params, **kwargs).owner.op.ndim_supp
617 create_size = find_size(shape=shape, size=size, ndim_supp=ndim_supp)
--> 618 rv_out = cls.rv_op(*dist_params, size=create_size, **kwargs)
620 rv_out.logp = _make_nice_attr_error("rv.logp(x)", "pm.logp(rv, x)")
621 rv_out.logcdf = _make_nice_attr_error("rv.logcdf(x)", "pm.logcdf(rv, x)")
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc_marketing/clv/distributions.py:301, in ParetoNBDRV.__call__(self, r, alpha, s, beta, T, size, **kwargs)
300 def __call__(self, r, alpha, s, beta, T, size=None, **kwargs):
--> 301 return super().__call__(r, alpha, s, beta, T, size=size, **kwargs)
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pytensor/tensor/random/op.py:311, in RandomVariable.__call__(self, size, name, rng, dtype, *args, **kwargs)
309 props["dtype"] = dtype
310 new_op = type(self)(**props)
--> 311 return new_op.__call__(
312 *args, size=size, name=name, rng=rng, dtype=dtype, **kwargs
313 )
315 res = super().__call__(rng, size, *args, **kwargs)
317 if name is not None:
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pymc_marketing/clv/distributions.py:301, in ParetoNBDRV.__call__(self, r, alpha, s, beta, T, size, **kwargs)
300 def __call__(self, r, alpha, s, beta, T, size=None, **kwargs):
--> 301 return super().__call__(r, alpha, s, beta, T, size=size, **kwargs)
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pytensor/tensor/random/op.py:315, in RandomVariable.__call__(self, size, name, rng, dtype, *args, **kwargs)
310 new_op = type(self)(**props)
311 return new_op.__call__(
312 *args, size=size, name=name, rng=rng, dtype=dtype, **kwargs
313 )
--> 315 res = super().__call__(rng, size, *args, **kwargs)
317 if name is not None:
318 res.name = name
File ~/miniconda3/envs/pymc_env/lib/python3.12/site-packages/pytensor/graph/op.py:293, in Op.__call__(self, name, return_list, *inputs, **kwargs)
249 def __call__(
250 self, *inputs: Any, name=None, return_list=False, **kwargs
251 ) -> Variable | list[Variable]:
252 r"""Construct an `Apply` node using :meth:`Op.make_node` and return its outputs.
253
254 This method is just a wrapper around :meth:`Op.make_node`.
(...)
291
292 """
--> 293 node = self.make_node(*inputs, **kwargs)
294 if name is not None:
295 if len(node.outputs) == 1:
TypeError: ParetoNBDRV.make_node() missing 1 required positional argument: 'T'