越學越懵了,計算機中是怎么進行采樣的,用了這么久的 rand() 函數,到現在才知道是怎么做的。
從均勻分布中采樣
計算機中通過 線性同余發生器(linear congruential generator,LCG)很容易從一個 $ x \sim Uniform[0, 1)$ 的均勻分布中進行采樣。如果要從 \(y \sim Uniform[a, b)\) 的均勻分布中采樣,只需要 \(x\) 的基礎上做個變換 \(y = (b-a)x + a\) 即可。
當然除了 LCG 外,還有其它均勻分布隨機數生成方法,這里不一一列舉,可以參考博客隨機數生成(一):均勻分布。
單獨把均勻分布采樣摘出來是因為它很基礎,很多其它采樣方法都是在該基礎上進行操作。
對離散型變量采樣
我們現在通過某種方法(比如 LCG)可以生成均勻分布的隨機數,這個時候我們就完全可以對某個含有有限個離散取值的變量 \(r\) 進行采樣,方法就是采用輪盤賭選擇法。
假設離散型變量 \(r\) 有 3 個取值,\(a_1, a_2, a_3\),概率分布如下圖所示:

所有取值概率之和為 1。此時我們可以從 \(Uniform[0, 1)\) 生成一個隨機數 \(b\),若 \(0 \le b < 0.6\),則選擇出 \(a_1\);若 \(0.6 \le b < 0.7\),則選擇出 \(a_2\);若 \(0.7 \le b < 1\),則選擇出 \(a_3\)。
對連續型變量采樣
上面我們已經討論了從均勻分布 \(U[a,b)\) 中采樣,對於其余分布,如高斯分布、gamma 分布、指數分布、t 分布、F 分布、Beta 分布、Dirichlet 分布等等,都可以基於 \(U[0,1)\) 的樣本生成。例如高斯分布可以通過 Box-Muller 變換得到:
【Box-Muller 變換】如果隨機變量 \(U_1,U_2\) 獨立且 \(U_1,U_2 \sim Uniform[0, 1]\),
則 \(Z_0, Z_1\) 獨立且服從標准正態分布。
想要得到服從 \(Z_2 \sim N(\mu, \sigma^2)\) 的高斯分布,則只需對 \(Z_0 \sim N(0, 1)\) 做如下變換:
對於更加一般分布 \(p(x)\),如下圖所示,我們該如何對其進行采樣呢?

這個時候我們可以使用 rejection sampling。
Rejection sampling 首先尋找一個簡單的分布 \(q(x)\),然后乘以一個常數 \(M\),使其滿足 \(p(x) \le M \cdot q(x)\),如下圖所示,\(q(x)\) 是一個高斯分布,\(M = 2\)。

在找到一個分布 \(2q(x)\) 能完全“覆蓋”分布 \(p(x)\) 后,我們任意 sample 一個樣本點 \(x_i\),但此時,我們將以 \(\frac{p(x_i)}{2q(x_i)}\) 的概率選擇去接收這個樣本,以 \((1 - \frac{p(x_i)}{2q(x_i)})\) 的概率選擇去拒絕該樣本。rejection sampling 平均會接收 \(\frac{1}{M}\) 個樣本點。
rejection sampling 優點:使用 rejection sampling 可以對大多數分布進行采樣,即使這些“分布”沒有進行歸一化。
rejection sampling 缺點:當 \(p(x)\) 和 \(2q(x)\) 相差太多時,rejection sampling 將拒絕大多數樣本點;其次,對於高維數據,常數 \(M\) 會很大,簡單使用 rejection sampling 所需要的樣本量隨空間維數增加而指數增長,即高維情況下不適合用 rejection sampling,此時 MCMC(Markov Chains Monte Carlo)和 Gibbs sampling 才是主流。(當然 MCMC 等既能處理離散情況也能處理連續情況。)
References
線性同余發生器 -- 百度百科
隨機數生成(一):均勻分布 -- MoussaTintin
LDA-math-MCMC 和 Gibbs Sampling -- 靳志輝
MCMC(一)蒙特卡羅方法 -- 劉建平Pinard
Bayesian Methods for Machine Learning: Sampling from 1-d distributions