python 边界为[0.1,0.5]的Beta分布

c7rzv4ha  于 2023-01-19  发布在  Python
关注(0)|答案(1)|浏览(114)

我想构造一个beta分布,其中mu和sigma分别为0.28和0.003,分布的边界为[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()

这似乎是可行的,然而,作为一个测试,我从相同的分布中抽样,我计算样本的平均值和标准差,得到的值与我开始时的值不同。
而且,这些值的最小值和最大值不是我想要的范围,所以我非常确定我没有正确使用loc和scale。

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()
hmae6n7t

hmae6n7t1#

您需要了解locscale参数背后的线性变换。
将随机变量 v1 转换为 v2 = loc + v1 * scale
所以你要像这个例子一样。

import scipy.stats

def get_ab(mean, var):
    assert(var < mean*(1-mean))
    var = (mean*(1-mean)/var - 1)
    return mean*var, (1-mean)*var

# v2 = 0.1 + v1 * 0.4
# v1 = (v2 - 0.1) / 0.4
a, b = get_ab((0.28-0.1)/0.4, (0.003/0.4)**2)
b = scipy.stats.beta(a=a, b=b, loc=0.1, scale=0.4)
print([b.mean(), b.std()])
# This will output '[0.28, 0.003]'.

相关问题