如何根据任意离散分布生成数字?

机器算法验证 分布
2022-02-07 20:14:52

如何根据任意离散分布生成数字?

例如,我有一组要生成的数字。假设它们从 1-3 标记如下。

1:4%、2:50%、3:46%

基本上,百分比是它们出现在随机数生成器输出中的概率。我有一个伪随机数生成器,它将在区间 [0, 1] 中生成均匀分布。有没有办法做到这一点?

我可以拥有多少个元素没有限制,但 % 加起来会达到 100%。

4个回答

从离散分布中采样的最佳算法之一是别名方法

别名方法(有效地)预先计算二维数据结构以将矩形划分为与概率成比例的区域。

数字

在来自参考站点的示意图中,单位高度的矩形已被划分为四种区域 - 按颜色区分 - 比例为,在为了从具有这些概率的离散分布中重复采样。垂直条具有恒定(单位)宽度。每一个都被分成一两个部分。片段的标识和垂直分区的位置存储在可通过列索引访问的表中。1/21/31/121/12

该表可以通过两个简单的步骤(每个坐标一个)进行采样,只需要生成两个独立的统一值和计算。这改进了反转离散 CDF 所需的计算,如此处其他回复中所述。O(1)O(log(n))

您可以在 R 中轻松完成此操作,只需指定所需的大小:

sample(x=c(1,2,3), size=1000, replace=TRUE, prob=c(.04,.50,.46))

在您的示例中,假设您绘制伪随机 Uniform[0,1] 值并将其命名为 U。然后输出:

1 如果 U<0.04

2 如果 U>=0.04 且 U<0.54

3 如果 U>=0.54

如果指定的 % 是 a, b, ...,则简单地输出

如果 U 则为 1

如果 U>=a 且 U<(a+b),则值为 2

等等

本质上,我们将 % 映射到 [0,1] 的子集,并且我们知道均匀随机值落入任何范围的概率只是该范围的长度。将范围按顺序排列似乎是最简单(如果不是唯一的话)的方法。这是假设您只询问离散分布;对于连续,可以做类似“拒绝采样”(维基百科条目)的事情。

假设有个可能的离散结果。根据累积概率质量函数划分为子区间,以给出分区区间m[0,1]F(0,1)

I1I2Im

其中在您的示例中Ij=(F(j1),F(j))F(0)0m=3

I1=(0,.04),     I2=(.04,.54),     I3=(.54,1)

因为F(1)=.04F(2)=.54F(3)=1

然后您可以使用以下算法生成分布XF

(1) 生成UUniform(0,1)

(2) 如果,则UIjX=j

  • 这一步可以通过查看是否小于每个累积概率并查看更改点(从)发生的位置来完成,这应该是在您正在使用的任何编程语言中使用布尔运算符的问题,并且找到第一个出现在向量中的位置。UTRUEFALSEFALSE

请注意,将恰好位于区间之一,因为它们是不相交的并且是分区UIj[0,1]