Gumbel 半分布

Gumbel half distribution

我使用下面的代码在 python 中使用 scipy 生成了概率密度函数:

import matplotlib.pyplot as plt
from scipy.stats import gumbel_l
import numpy as np

data = gumbel_l.rvs(size=100000)
data = np.sort(data)

plt.hist(data, bins=50, density=True)
plt.plot(data, gumbel_l.pdf(data))
plt.show()

我的问题是,是否有一种方法可以获得此分布的单尾分布,即分布的左侧,既可以生成它又可以使其适合 pdf。

您可以创建自定义 rv_continuous subclass。最低要求是自定义 class 提供 pdfpdf 可以从 gumbel_lpdf 直到 x = 0 获得,对于正值 x 为零。 pdf 需要归一化以使其面积等于 1,为此我们可以除以 gumbel_lcdf(0).

仅实施了 pdf,您会注意到获取随机变量 (.rvs) 会相当缓慢。 解释说这可以通过生成太多变量并丢弃太高的值来解决,或者通过为 ppf.

提供一个实现来解决。

由于 ppf 可以直接从 gumbel_lppf 获得,下面的代码实现了该解决方案。可以使用类似的方法在另一个位置截断,甚至可以在两个位置截断。

import matplotlib.pyplot as plt
from scipy.stats import gumbel_l, rv_continuous
import numpy as np

class gumbel_l_trunc_gen(rv_continuous):
    "truncated gumbel_l distribution"

    def __init__(self, name='gumbel_l_trunc'):
        self.gumbel_l_cdf_0 = gumbel_l.cdf(0)
        self.gumbel_trunc_normalize = 1 / self.gumbel_l_cdf_0
        super().__init__(name=name)

    def _pdf(self, x):
        return np.where(x <= 0, gumbel_l.pdf(x) * self.gumbel_trunc_normalize, 0)

    def _cdf(self, x):
        return np.where(x <= 0, gumbel_l.cdf(x) * self.gumbel_trunc_normalize, 1)

    def _ppf(self, x):
        return gumbel_l.ppf(x * self.gumbel_l_cdf_0)

gumbel_l_trunc = gumbel_l_trunc_gen()

data = gumbel_l_trunc.rvs(size=100000)

x = np.linspace(min(data), 1, 500)
plt.hist(data, bins=50, density=True)
plt.plot(x, gumbel_l_trunc.pdf(x))
plt.show()