跳至主要內容

逆变换采样

荒流数学coding大约 2 分钟约 465 字

一般的编程语言都具有(伪)随机数生成功能,如 python 的random.random()函数,然而它们通常只对应均匀分布。那如果想生成符合任意概率分布的随机数,该如何在代码上实现呢?这就可以用到“逆变换采样”了。

1. 引理

假设XX为一个连续随机变量,其累积分布函数为CDF(x)=P(Xx)CDF(x)=P(X \le x),若随机变量Y=CDF(X)Y=CDF(X),则YY服从区间[0,1][0, 1]上的均匀分布。

证明:已知:CDF(x)[0,1]CDF(x) \in [0, 1],且CDF(x)CDF(x)为单调递增函数。

  y<0,P(Yy)=P(CDF(X)y)=0 \forall \; y < 0, \qquad P(Y \le y)=P(CDF(X) \le y)=0

  0y1,P(Yy)=P(CDF(X)y)=P(XCDF1(y))=P(Xx)=CDF(x)=y \begin{aligned} \forall \; 0 \le y \le 1,\qquad P(Y \le y) &= P(CDF(X)\le y) \\ &= P(X\le CDF^{-1}(y)) \\ &= P(X\le x) \\ &= CDF(x) \\ &= y \end{aligned}

  y>1,P(Yy)=P(CDF(X)y)=1 \forall \; y > 1, \qquad P(Y\le y) = P(CDF(X) \le y) = 1

综上,YY服从区间[0,1][0,1]上的均匀分布。

2. 推论:逆变换采样

假设XX为一个连续随机变量,其累积分布函数为CDF(x)=P(Xx)CDF(x)=P(X \le x),则随机变量Y=CDF(X)Y=CDF(X)服从区间[0,1][0, 1]上的均匀分布。逆变换采样即是将该过程反过来进行:

  1. 首先对于随机变量YY,我们从[0,1][0,1]中随机均匀抽取一个数yy
  2. 由于X=CDF1(Y)X=CDF^{-1}(Y),可求得随机数x=CDF1(y)x=CDF^{-1}(y),故xx即可看作是从分布CDF(X)CDF(X)中生成的随机样本。

3. 联想

突然想到一个疑问,似乎概率论课堂中有讲过但是一时又无法想出解答,暂记如下:

问题:设有连续随机变量XXYY,已知XX的概率密度为p1(x)p_1(x),且XXYY有如下关系:

y=f(x) y=f(x)

那么YY的概率密度p2(y)p_2(y)可如何表示?