如何生成指定分佈的隨機數

超人汪小建發表於2018-04-26

前言

對於隨機數平時我們還是比較常用的,一般都會直接通過各種語言原生自帶的隨機函式,比如 c++ 中有random()函式,java 中有 Random 類,python 有 random 模組等等。都能很方便生成隨機變數,但它們有一個特點,那就是都服從均勻分佈,而有些場景需要要生成不同分佈的隨機變數。

隨機變數

隨機變數即隨機函式,通過該函式能生成每個可能事件對應的一個值。比如我們擲骰子,每次按一定的概率生成一個值。有兩種型別變數,

  • 離散型隨機變數,能取到的不相同的值是有限個或可列無限多個。
  • 連續型隨機變數,能取到的值可以是連續的,在某個區間內可取任意一實數。

概率密度函式

主要用來表示不同點對應的概率大小,即X軸上每個單位長度對應的概率大小。概率等於面積,當某區間長度趨於0時則變為一個點,此時概率大小為f(x)。

常見分佈

  • 伯努利分佈,即0-1分佈,隨機變數為0或為1,概率為p和1-p。
  • 二項分佈,進行n次伯努利實驗,相對於不同成功次數對應的概率。
  • 泊松分佈,是二項分佈的極限形式。
  • 均勻分佈,在相同長度間隔的分佈概率是等可能的。
  • 正態分佈,又名高斯分佈,正態曲線呈鍾型,兩頭低,中間高。
  • 指數分佈,描述事件以恆定平均速率連續且獨立地發生的過程的概率分佈。
  • 邏輯斯蒂分佈,增長分佈,形狀有點像正態分佈。

生成分佈演算法

  • Inverse Transform Method,首先生成一個均勻分佈的隨機數,再求指定分佈的分佈函式F(x),然後求得F(x)的逆函式G(x),將隨機數帶入逆函式得到的即為指定分佈的隨機數。
  • Acceptance-Rejection Method,首先生成一個均勻分佈隨機數a,設概率密度函式為f(x),然後再生成一個均勻分佈隨機數b,若b<=f(a),則成功得到指定分佈的隨機數,否則從頭開始。

實現

兩種演算法都比較容易理解,第一個需要求逆函式,有時並不好求,而第二個基本沒什麼限制,對於任何分佈都能很完成任務。下面就用第二種方法實現生成幾種分佈的隨機數。

正態分佈

def normal_pdf(x, mu=0, sigma=1):
    return (1 / (math.sqrt(2 * math.pi) * sigma)) * (math.exp(-math.pow(x - mu, 2) / (2 * math.pow(sigma, 2))))
    
def standard_normal_rand():
    while True:
        a = random.uniform(-4.0, 4.0)
        b = random.uniform(0.0, 3.0)
        if b < normal_pdf(a):
            return a, b
複製程式碼

這裡寫圖片描述

指數分佈

def exponential_pdf(x, lam=1):
    return lam * math.exp(-lam * x)
    
def exponential_rand():
    while True:
        a = random.uniform(0.0, 100.0)
        b = random.uniform(0.0, 3.0)
        if b <= exponential_pdf(a):
            return a, b
複製程式碼

這裡寫圖片描述

泊松分佈

def poisson_pdf(x, lam=1):
    return (math.pow(lam, x) / math.factorial(x)) * math.exp(-lam)

def poisson_rand():
    while True:
        a = random.randint(0, 50)
        b = random.uniform(0.0, 1.0)
        if b <= poisson_pdf(a):
            return a, b
複製程式碼

這裡寫圖片描述

github

https://github.com/sea-boat/MachineLearning_Lab/blob/master/distribution_gen.py

-------------推薦閱讀------------

我的2017文章彙總——機器學習篇

我的2017文章彙總——Java及中介軟體

我的2017文章彙總——深度學習篇

我的2017文章彙總——JDK原始碼篇

我的2017文章彙總——自然語言處理篇

我的2017文章彙總——Java併發篇


跟我交流,向我提問:

這裡寫圖片描述

公眾號的選單已分為“分散式”、“機器學習”、“深度學習”、“NLP”、“Java深度”、“Java併發核心”、“JDK原始碼”、“Tomcat核心”等,可能有一款適合你的胃口。

為什麼寫《Tomcat核心設計剖析》

歡迎關注:

這裡寫圖片描述

相關文章