在Python中规范化后验分布时遇到问题

在Python中规范化后验分布时遇到问题,python,bayesian,Python,Bayesian,在我读过的一篇论文中,我对狄里克莱多项式后验的推导进行了编码,我很难将分布求和为1。以下是未简化形式的代码: def pcn(X, n, N, c, alpha): pnc = np.math.factorial(np.sum([n[i] for i in range(len(n))]))/ \ np.product([np.math.factorial(n[i]) for i in range(len(n))])* \ np.product([c

在我读过的一篇论文中,我对狄里克莱多项式后验的推导进行了编码,我很难将分布求和为1。以下是未简化形式的代码:

def pcn(X, n, N, c, alpha):
    pnc = np.math.factorial(np.sum([n[i] for i in range(len(n))]))/ \
          np.product([np.math.factorial(n[i]) for i in range(len(n))])* \
          np.product([c[i]**n[i] for i in range(len(n))])
    pc = G(len(X)*alpha)/ \
         np.product([G(alpha) for i in range(len(n)) if i in X])* \
         np.product([(c[i])**(alpha - 1) for i in range(len(n)) if i in X])
    pn = np.math.factorial(N)/ \
         np.product([np.math.factorial(n[i]) for i in range(len(n)) if i in X])* \
         G(len(X)*alpha)/ \
         G(len(X)*alpha + N)* \
         np.product([G(alpha + n[i])/G(alpha) for i in range(len(n)) if i in X])
    return pnc
我在这里对其进行了简化,删除了被分割的部分:

def pcns(X, n, N, c, alpha):
    pnc = np.product([c[i]**n[i] for i in range(len(n))])

    pc = np.product([(c[i])**(alpha - 1) for i in range(len(n))])/ \
         np.product([G(alpha) for i in range(len(n))])

    pn = np.product([G(alpha + n[i])/G(alpha) for i in range(len(n))])/ \
         G(len(X)*alpha + N)

    return pnc * pc / pn
我设置输入变量并将c数组初始化为输入:

X = [0,1]
n = [6.0, 3.0]
N = sum(n)
alpha = 20
c = np.linspace(0, 1, 1000)
然后我在c上迭代,在每个c上计算后验函数,并绘制:

dist = []
for i in c:
    dist.append(pcns(X, n, N, [i, 1-i], alpha))

plt.plot(c,dist)


当我对
dist
求和时得到的值是999或
len(c)-1
。有谁会碰巧知道为什么它不是1;dr:你在计算一个定积分的离散近似值,却忘了用dx~=delta_x乘以这些数值


即使这是一个正确的标准化概率分布,为什么
dist
和为1?因为我们没有<代码> G <代码>,我不能精确地复制你的结果,所以我们来考虑一个简单的高斯。我们可以将平均值设置为0.5,将STDEV设置为较小的值,因此0到1的范围应包含大部分概率:

>>> import scipy.stats
>>> c = np.linspace(0, 1, 1000)
>>> p = scipy.stats.norm(0.5,0.02).pdf(c)
>>> sum(p)
999.00000000000045
又是999。但是,为什么这应该是1?应该是一的数量是总的综合概率。这里我们只取一些点的概率分布函数的值,并将它们相加

更简单的例子:我们知道x^2从0到1的定积分是1/3,但是

>>> x = np.linspace(0, 1, 1000)
>>> sum(x**2)
333.50016683350009
当我们真的想要类似的东西时(粗略的矩形近似,略高于期望的答案,因为我们包含了x=1点的贡献,而这个盒子实际上在积分区域之外):

还是你以前的情况

>>> sum(p) * (c[1]-c[0])
1.0000000000000004

注意这里我们可以写
*(c[1]-c[0])
,因为
c
是等距的,所以
Int(p(x)dx)~=sum(p[x]*delta_x)
中的每个“dx”是相同的。一般来说,我们想要的东西更像
sum(p[:-1]*np.diff(c))

太棒了!谢谢你提供了信息丰富的答案。顺便说一下,G函数是伽马函数。对不起,我在很困的时候写的。
>>> sum(p) * (c[1]-c[0])
1.0000000000000004