# Reparametrized Beta(μ, σ²) in Turing: how to set a prior that depends on another parameter?

**URL:** https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753
**Category:** Probabilistic Programming
**Tags:** turing
**Created:** [July 8, 2024, 7:41am UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753 "2024-07-08T07:41:19Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![DominiqueMakowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dominiquemakowski/32/51410_2.png) [@DominiqueMakowski](https://discourse.julialang.org/u/DominiqueMakowski)
#### Post date: [July 8, 2024, 7:41am UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753/1 "2024-07-08T07:41:19Z")

</div>

I am trying to model data between ]0, 1[ using Bayesian regressions in Turing.

It is fairly common to use a Mean/Variance parametrization to the Beta (see [Wikipedia](https://en.wikipedia.org/wiki/Beta_distribution#Mean_and_variance)), allowing to express priors on intuitive quantities. This is the default Beta parametrization used in R’s _brms_ (see [this explanation](https://discourse.mc-stan.org/t/understanding-parameters-of-beta-family-in-brms/21640/2))

Here is my MeanVarBeta wrapper:

```julia
using Turing, Distributions, Random

# Reparameterized Beta distribution
function MeanVarBeta(μ, σ²)
    if σ² <= 0 || σ² >= μ * (1 - μ)
        error("Variance σ² must be in the interval (0, μ*(1-μ)=$(μ*(1-μ))).")
    end

    ν = μ * (1 - μ) / σ² - 1
    α = μ * ν
    β = (1 - μ) * ν

    return Beta(α, β)
end

```

- My first question is: is this reparametrized Beta already implemented in a package (I didn’t see it in Distributions)? To make sure it’s correct and so that I don’t want to reinvent the wheel.

The key issue is that this distribution’s parameters depend on one another (var must be `< μ*(1-μ)`. In red are the possible joint parameter space:

![image](https://global.discourse-cdn.com/julialang/original/3X/d/9/d94246ecec2dabd1898b241f4d3296eddf3b2627.png)

Here’s a potential Turing Beta reg model:

```julia
@model function model_Beta(x)
    μ ~ truncated(Beta(1,1), 0.3, 0.7)
    σ ~ Uniform(0.05, 0.15)
    x = MeanVarBeta(μ, σ)
end
chains = sample(model_Beta(rand(MeanVarBeta(0.5, 0.1), 100)), NUTS(), 300)

```

As you can see, I had to be very strict with the priors to avoid exploring the space where it errors (when `var > μ*(1-μ)`).

- My second question is: how can we specify the priors / the model to avoid exploring the parameter space conditionally on another prior parameter?

---

<div class="post-metadata">

### Author: ![mhauru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhauru/32/208880_2.png) [@mhauru](https://discourse.julialang.org/u/mhauru)
#### Post date: [July 8, 2024, 1:48pm UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753/2 "2024-07-08T13:48:14Z")

</div>

For the latter question, does `σ ~ Uniform(esp(typeof(μ)), μ * (1 - μ) - esp(typeof(μ)))` solve the problem? Priors of one parameter can depend on another, and if the prior is zero in the forbidden region then that should never get explored.

---

<div class="post-metadata">

### Author: ![DominiqueMakowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dominiquemakowski/32/51410_2.png) [@DominiqueMakowski](https://discourse.julialang.org/u/DominiqueMakowski)
#### Post date: [July 8, 2024, 2:44pm UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753/3 "2024-07-08T14:44:01Z")

</div>

That looks like exactly what we’d need, thanks!  
But I’m having trouble understanding what for are `esp()` and `typeof()`, and I didn’t find much documentation on conditional prior parameters on google 😕

Do you know if this syntax is described somewhere or not yet?

---

<div class="post-metadata">

### Author: ![mhauru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mhauru/32/208880_2.png) [@mhauru](https://discourse.julialang.org/u/mhauru)
#### Post date: [July 8, 2024, 3:03pm UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753/4 "2024-07-08T15:03:04Z")

</div>

Oh sorry, first of all I had a typo, it should say `eps` rather than `esp`. Second, that’s all unnecessary fanciness, `eps(typeof(μ))` gets the smallest magnitude number representable using the type of the variable `μ`. Most probably `μ` is a 64bit floating point number, in which case `eps(typeof(μ))` is roughtly `2.2e-16`. `Uniform(eps(typeof(μ)), μ * (1 - μ) - eps(typeof(μ)))` is essentially just `Uniform(0, μ * (1 - μ))`, except both of the ends are moved a tiny bit to avoid the problematic end points of the interval.

---

<div class="post-metadata">

### Author: ![DominiqueMakowski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dominiquemakowski/32/51410_2.png) [@DominiqueMakowski](https://discourse.julialang.org/u/DominiqueMakowski)
#### Post date: [July 8, 2024, 3:35pm UTC](https://discourse.julialang.org/t/reparametrized-beta-in-turing-how-to-set-a-prior-that-depends-on-another-parameter/116753/5 "2024-07-08T15:35:19Z")

</div>

Thanks a lot it’s all clear now (and it works 🙂)

Here’s the full model if others are interested:

```julia
using Turing, Distributions, Random

# Reparameterized Beta distribution
function MeanVarBeta(μ, σ²)
    if σ² <= 0 || σ² >= μ * (1 - μ)
        error("Variance σ² must be in the interval (0, μ*(1-μ)=$(μ*(1-μ))).")
    end

    ν = μ * (1 - μ) / σ² - 1
    α = μ * ν
    β = (1 - μ) * ν

    return Beta(α, β)
end

@model function model_Beta(x)
    μ ~ Beta(1, 1)
    σ ~ Uniform(eps(typeof(μ)), μ * (1 - μ) - eps(typeof(μ)))
    for i in 1:length(x)
        x[i] ~ MeanVarBeta(μ, σ)
    end
end
chains = sample(model_Beta(rand(MeanVarBeta(0.5, 0.2), 200)), NUTS(), 500; 
   initial_params=[0.5, 0.1])

```
