I'd like to construct a beta distribution where the mu and sigma are 0.28 and 0.003, respectively, and the distribution is bound at [0.1, 0.5].
import numpy as np
import pandas as pd
import plotly.express as px
from scipy import stats
mu = 0.28
stdev = 0.003
lb = 0.1
ub = 0.5
def calc_alpha(x, y):
res = x * ((x*(1-x) / y**2)-1)
return res
def calc_beta(x, y):
res = (1 - x) * ((x*(1-x) / y**2)-1)
return res
alpha_ = calc_alpha(mu, stdev)
beta_ = calc_beta(mu, stdev)
x = np.linspace(lb, ub, 100000)
y = stats.beta(alpha_, beta_, loc = lb, scale = ub).pdf(x)
fig = px.line(x=x, y=y)
fig.show()
This seems to work. However, as a test, I sample from the same distribution, and I calculate the mean and standard deviation of the sample and get different values than what I started out with.
Also, the min and max of these values isn't the range I want, so pretty sure that I'm not using loc and scale correctly.
beta_rands = stats.beta(alpha_, beta_, loc = lb, scale = ub).rvs(1000000)
# 0.24
beta_rands.mean()
# 0.0014
beta_rands.std()
#0.232
beta_rands.min()
#0.247
beta_rands.max()
You need to understand the linear transformation underlying the
locandscaleparameters.Let
v1andv2be random variables corresponding tobeta(a=a, b=b)andbeta(a=a, b=b, loc=loc, scale=scale)respectively. Thenv1is transformed intov2 = loc + v1 * scale. Sincev1is in [0, 1],v2is in [loc,loc + scale]. (See notes in the official documentation.)You want
v2to be in [0.1, 0.5], solocandscaleshould be 0.1 and 0.4 respectively.You want the mean and standard deviation of
v2to be 0.28 and 0.003 respectively, so the mean and standard deviation ofv1should be (0.28-0.1)/0.4 and 0.003/0.4 respectively, becausev1 = (v2 - 0.1) / 0.4.(A shift does not change the standard deviation. See the properties of the standard deviation.)The following example shows the implementation.