用给定的概率密度函数生成随机数

2024-07-06 22:13:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我想指定一个分布的probably density function,然后用python从该分布中提取N个随机数。我该怎么做呢?


Tags: functiondensityprobably
2条回答

一般来说,你需要一个逆累积概率密度函数。一旦有了它,就可以简单地沿分布生成随机数:

import random

def sample(n):
    return [ icdf(random.random()) for _ in range(n) ]

或者,如果使用NumPy:

import numpy as np

def sample(n):
    return icdf(np.random.random(n))

在这两种情况下,icdf是反向累积分布函数,它接受0到1之间的值,并从分布中输出相应的值。

为了说明icdf的性质,我们将以值10和12之间的简单均匀分布为例:

  • 概率分布函数在10到12之间为0.5,其他地方为零

  • 累积分布函数为0小于10(10以下无样本),1大于12(12以上无样本),且在值之间线性增加(PDF的整数)

  • 反向累积分布函数仅定义在0和1之间。在0时为10,在12时为1,并且在值之间线性变化

当然,最困难的部分是求逆累积密度函数。它实际上取决于你的分布,有时你可能有一个分析函数,有时你可能想诉诸插值。数值方法可能是有用的,因为数值积分可用于创建CDF,插值可用于反转CDF。

这是我的函数,用于检索根据给定概率密度函数分布的单个随机数。我用了蒙特卡罗的方法。当然,可以通过调用这个函数n次来生成随机数。

    """
    Draws a random number from given probability density function.

    Parameters
    ----------
        pdf       -- the function pointer to a probability density function of form P = pdf(x)
        interval  -- the resulting random number is restricted to this interval
        pdfmax    -- the maximum of the probability density function
        integers  -- boolean, indicating if the result is desired as integer
        max_iterations -- maximum number of 'tries' to find a combination of random numbers (rand_x, rand_y) located below the function value calc_y = pdf(rand_x).

    returns a single random number according the pdf distribution.
    """
    def draw_random_number_from_pdf(pdf, interval, pdfmax = 1, integers = False, max_iterations = 10000):
        for i in range(max_iterations):
            if integers == True:
                rand_x = np.random.randint(interval[0], interval[1])
            else:
                rand_x = (interval[1] - interval[0]) * np.random.random(1) + interval[0] #(b - a) * random_sample() + a

            rand_y = pdfmax * np.random.random(1) 
            calc_y = pdf(rand_x)

            if(rand_y <= calc_y ):
                return rand_x

        raise Exception("Could not find a matching random number within pdf in " + max_iterations + " iterations.")

在我看来,如果不必检索大量随机变量,这个解决方案的性能比其他解决方案要好。另一个好处是,您只需要PDF并避免计算CDF、逆CDF或权重。

相关问题 更多 >