使用 scipy.stats.rv_continuous 的上限问题

Upper bound problem using scipy.stats.rv_continuous

我想从我自己生成一个有界分布函数。但我在上限看到了一个奇怪的行为。这是我的代码:

import matplotlib.pyplot as plt
from scipy.stats import rv_continuous

def gaus(x, mu, sig):
    return exp(-0.5*((x-mu)/sig)**2)/(sig*sqrt(2*pi))

class gaussian_gen(rv_continuous):
    def _pdf(self, x):
        return gaus(x,0.2,0.1)

gaussian = gaussian_gen(a=0.0,b=1)
plt.hist(gaussian.rvs(size=1000),bins=100)
plt.show()

剧情是这样的: when it is centered at 0.2 我注意到当高斯中心靠近边界时,这种行为会增加。有什么问题?

方法_pdf()需要一个在概率密度函数范围内正确归一化的函数。如果[a, b]范围内的积分不是1,scipy将PDF的剩余权重放在上界。也就是说,当您的 mu 接近边界时,您开始在 1 处看到此功能。

要更正此问题,我们可以修改 class 以存储我们关心的边界之间的 PDF 积分,并将 _pdf() 的 return 除以该值。下面的代码解决了这个问题。

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import rv_continuous
from scipy.integrate import quad


def gaus(x, mu, sig):
    return np.exp(-0.5*((x-mu)/sig)**2)/(sig*np.sqrt(2*np.pi))

class gaussian_gen(rv_continuous):
    def __init__(self, mu, sig, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.mu = mu
        self.sig = sig

        # Perform integration in the range we care about
        self.integral, _ = quad(gaus, self.a, self.b, args=(self.mu, self.sig))

    def _pdf(self, x):
        # Return the normalized pdf
        return gaus(x,self.mu, self.sig) / self.integral

gaussian = gaussian_gen(0.2, 0.2, a=0., b=1.)
plt.hist(gaussian.rvs(size=1000),bins=100)
plt.show()

给出以下采样分布

它在边缘周围表现正确。