# Do posterior predictive with customDist function with error message (random() missing 1 required...)

**URL:** <https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379>\
**Category:** General\
**Created:** [May 3, 2024, 3:53am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379 "2024-05-03T03:53:32Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![JoshYang1977](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/joshyang1977/32/7633_2.png) [@JoshYang1977](https://discourse.pymc.io/u/JoshYang1977)\
**Post date:** [May 3, 2024, 3:53am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/1 "2024-05-03T03:53:32Z")

</div>

Hello all,

I am writing a code to do posterior predictive with a customDist function. My code is listed below. The error message there is returned is “random() missing 1 required positional argument: ‘beta’”. If my code is just doing sampling (pm.sample), it is fine. The error message came up when I did posterior predictive. I do not know where to add the positional argument accordingly. Thank you very much for your kind reply.

```
with pm.Model(coords=coords) as model:

        x = pm.MutableData("x", x_train)
        rloss = pm.MutableData("rloss", rloss_train)
        
        # Priors
        a = pm.Normal("a", mu=0, sigma=1, dims="coeffs")
        b = pm.Normal("b", mu=0, sigma=1, dims="coeffs")
    
        # Linear model
        a1 = pm.math.dot(x, a)
        b1 = pm.math.dot(x, b)
    
        # Link function
        mu = pm.Deterministic("mu", pm.math.invlogit(a1))
        phi = pm.Deterministic("phi", pm.math.exp(b1))
        alpha = pm.Deterministic("alpha", mu * phi)
        beta = pm.Deterministic("beta", (1 - mu) * phi)

        def logp_beta(obsLoss, alpha, beta): 
            return pm.logp(pm.Beta.dist(alpha=alpha, beta=beta), obsLoss)

        def random(obsLoss, alpha, beta, rng= None, size=None) :
            return pm.Beta.dist(alpha, beta).random(size=size)

        # Likelihood using the custom distribution
        rloss_custom = pm.CustomDist('rloss_custom', alpha, beta, logp=logp_beta, random=random, observed=rloss)

    with model:
        step = pm.Metropolis()
        idata = pm.sample(1200, step=step, chains=4)

    with model:
        pm.set_data({"x": x_test}, coords = {"coeffs": labels})
        pp = pm.sample_posterior_predictive(idata, predictions=True).predictions

```

---

<div class="post-metadata">

**Author:** ![jessegrabowski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/jessegrabowski/32/5010_2.png) [@jessegrabowski](https://discourse.pymc.io/u/jessegrabowski)\
**Post date:** [May 3, 2024, 4:46am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/2 "2024-05-03T04:46:16Z")

</div>

If you check the docstring for `pm.CustomDist`, it says the signature for the `random` function should be `random(*dist_params, rng=None, size=None)`. So basically you don’t need `obsLoss` as an input there.

---

<div class="post-metadata">

**Author:** ![JoshYang1977](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/joshyang1977/32/7633_2.png) [@JoshYang1977](https://discourse.pymc.io/u/JoshYang1977)\
**Post date:** [May 3, 2024, 6:11am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/3 "2024-05-03T06:11:40Z")

</div>

Thank you so much. I removed obsLoss in the def random. Now there is another error came up “The `rv.random()` method was removed. Instead use `pm.draw(rv)`.`”

Any quick thought?

Thank you

---

<div class="post-metadata">

**Author:** ![jessegrabowski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/jessegrabowski/32/5010_2.png) [@jessegrabowski](https://discourse.pymc.io/u/jessegrabowski)\
**Post date:** [May 3, 2024, 6:17am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/4 "2024-05-03T06:17:26Z")

</div>

Basically do what it says? Since you can’t use `pm.Beta().random`, instead use `pm.draw(pm.Beta.dist(...)`. But this will be slow; you shouldn’t do it either. The `random` function isn’t a pytensor graph, so you can just directly use `scipy.stats.beta(...).rvs(size)`

---

<div class="post-metadata">

**Author:** ![ricardoV94](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/ricardov94/32/5775_2.png) [@ricardoV94](https://discourse.pymc.io/u/ricardoV94)\
**Post date:** [May 3, 2024, 6:20am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/5 "2024-05-03T06:20:34Z")

</div>

Or you can use the new dist kwarg and then neither logp or random are needed, the docs have some code examples

---

<div class="post-metadata">

**Author:** ![JoshYang1977](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/joshyang1977/32/7633_2.png) [@JoshYang1977](https://discourse.pymc.io/u/JoshYang1977)\
**Post date:** [May 3, 2024, 6:23am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/6 "2024-05-03T06:23:21Z")

</div>

I would really appreciate it if you could show me the link to the document?  
Much appreciated

---

<div class="post-metadata">

**Author:** ![ricardoV94](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/ricardov94/32/5775_2.png) [@ricardoV94](https://discourse.pymc.io/u/ricardoV94)\
**Post date:** [May 3, 2024, 6:29am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/7 "2024-05-03T06:29:27Z")

</div>

Google should always find the page you need: [pymc.CustomDist — PyMC 5.14.0 documentation](https://www.pymc.io/projects/docs/en/stable/api/distributions/generated/pymc.CustomDist.html)

---

<div class="post-metadata">

**Author:** ![JoshYang1977](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/joshyang1977/32/7633_2.png) [@JoshYang1977](https://discourse.pymc.io/u/JoshYang1977)\
**Post date:** [May 3, 2024, 6:32am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/8 "2024-05-03T06:32:10Z")

</div>

Thank you so much. I have read it before and I will read it again.

---

<div class="post-metadata">

**Author:** ![JoshYang1977](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/joshyang1977/32/7633_2.png) [@JoshYang1977](https://discourse.pymc.io/u/JoshYang1977)\
**Post date:** [May 3, 2024, 7:22am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/9 "2024-05-03T07:22:26Z")

</div>

Thank you for your help. I have changed my code as follows. I use scipy.stats.beta(alpha, beta).rvs(size) and the old problem is solved. The code does posterior\_predictive. However, the error message returned is “ValueError: size does not match the broadcast shape of the parameters. (499,), (499,), (215,)”. The number of x\_train is 499 and the number of x\_test is 215. Since I use set\_data and it should be 215. Not sure why 499 appears. Should I run the posterior\_predictive with a new model? Thank you very much.

```
with pm.Model(coords=coords) as model:
    # Data containers
    x = pm.MutableData("x", x_train)
    rloss = pm.MutableData("rloss", rloss_train)
    
    # Priors
    a = pm.Normal("a", mu=0, sigma=1, dims="coeffs")
    b = pm.Normal("b", mu=0, sigma=1, dims="coeffs")

    # Linear model
    a1 = pm.math.dot(x, a)
    b1 = pm.math.dot(x, b)

    # Link function
    mu = pm.Deterministic("mu", pm.math.invlogit(a1))
    phi = pm.Deterministic("phi", pm.math.exp(b1))
    alpha = pm.Deterministic("alpha", mu * phi)
    beta = pm.Deterministic("beta", (1 - mu) * phi)
    
    
    def logp_beta(obsLoss, alpha, beta): 
        return pm.logp(pm.Beta.dist(alpha=alpha, beta=beta), obsLoss)
    
    def random(alpha, beta, rng= None, size=None) :
        return scipy.stats.beta(alpha, beta).rvs(size)

    # Likelihood using the custom distribution
    rloss_custom = pm.CustomDist('rloss_custom', alpha, beta, logp=logp_beta, random=random, observed=rloss)
    
with model:
    step = pm.Metropolis()
    idata = pm.sample(1200, step=step, chains=4)

az.plot_posterior(idata, var_names=["a", "b"])
plt.show()

# Generate posterior predictive samples

with model:
    pm.set_data({"x": x_test}, coords = {"coeffs": labels})
    pp = pm.sample_posterior_predictive(idata, predictions=True).predictions

```

---

<div class="post-metadata">

**Author:** ![jessegrabowski](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/jessegrabowski/32/5010_2.png) [@jessegrabowski](https://discourse.pymc.io/u/jessegrabowski)\
**Post date:** [May 3, 2024, 7:39am UTC](https://discourse.pymc.io/t/do-posterior-predictive-with-customdist-function-with-error-message-random-missing-1-required/14379/10 "2024-05-03T07:39:58Z")

</div>

This is a common “gotcha” when using pm.set\_data. Although the `rloss` data is not used in posterior predictive sampling, it’s still being used to infer the shape of the outputs, which is then causing an error. You can prevent this by explicitly linking the shape of `rloss_custom` to the shape of `x` like this:

```auto
    rloss_custom = pm.CustomDist('rloss_custom', alpha, beta, logp=logp_beta, random=random, observed=rloss, shape=x.shape[0])

```

PyMC will then know to automatically update that shape when `x` changes. You can see the [data container example notebook](https://www.pymc.io/projects/examples/en/latest/fundamentals/data_container.html#applied-example-using-mutabledata-as-input-to-a-binomial-glm) for more discussion on this point.
