Python中的np.random.binomial()二項式分佈函數詳解

看了很多博客,感覺很多人對np.random.binomial()的解釋都寫得不是很清楚,或者寫錯了,特別是對該函數的參數解釋。本文以二項式分佈的理論概念爲起點,對該函數進行解釋,歡迎討論指正。

二項式分佈

二項分佈是由伯努利提出的概念,指的是重複n次(注意:這裏的n和binomial()函數參數n不是一個意思)獨立的伯努利試驗,如果事件X服從二項式分佈,則可以表示爲X~B(n,p),則期望E(X)=np,方差D(X)=np(1-p)。簡單來講就是在每次試驗中只有兩種可能的結果(例如:拋一枚硬幣,不是正面就是反面,而擲六面體色子就不是二項式分佈),而且兩種結果發生與否互相對立,並且相互獨立,與其它各次試驗結果無關,事件發生與否的概率在每一次獨立試驗中都保持不變。

函數原型及參數:numpy.random.binomial(n,p,size=None)

官方參數的解釋如下:

參數 解釋
n int型或者一個int型的數組,大於等於0,接受浮點數但是會被截斷(官方解釋:n is truncated to an integer,例如:輸入4.6或者4.2都會被當做4來計算)成整數來使用。
p float或者一組float的數組,0≤p≤1;
size 可選項,int或者int的元組,表示的輸出的大小,如果提供了size,例如(m,n,k),那麼會返回m×n×k個數值。如果size=None,也就是默認沒有的情況,當n和p都是一個數字的時候只會返回一個值,否則返回的是np.broadcast(n,p).size個數值。
reture 返回值。size是一個整數N時,返回一個長度爲N的一維數組;size是(X,Y)類型元組時,返回一個X行Y列二維數組;size是(X,Y,Z)類型元組時,返回一個三維數組(三維數組不能以三維形式直接輸出,會輸出X個Y行Z列的二維數組,以此類推)。

官方解釋中只規定了參數的類型和範圍,但是並沒有給出具體的數學意義,不便於理解。現在對逐個參數進行解釋:

參數n一次試驗的樣本數n,並且相互不干擾。 有些博客解釋這裏的參數n是試驗次數,我認爲不對,或許現在看起來好像一次試驗n個互不相干的樣本n次試驗一個樣本是一樣的,但是如果把n理解爲試驗次數,那和size參數的意義會產生衝突;

參數p:事件發生的概率p,範圍[0,1]。這裏有個理解的關鍵就是 “事件發生”到底是指的什麼事件發生?準確來講是指:如果一個樣本發生的結果要麼是A要麼是B,事件發生指的是該樣本其中一種結果發生。

參數size:限定了返回值的形式(具體見上面return的解釋)和實驗次數。當size是整數N時,表示實驗N次,返回每次實驗中事件發生的次數;size是(X,Y)時,表示實驗X*Y次,以X行Y列的形式輸出每次試驗中事件發生的次數。(如果將n解釋爲試驗次數而不是樣本數的話,這裏返回數組中數值的意義將很難解釋)。

return返回值 : 以size給定的形式,返回每次試驗事件發生的次數,次數大於等於0且小於等於參數n。注意:每次返回的結果具有隨機性,因爲二項式分佈本身就是隨機試驗。

給出幾個例子:

例1: n=1時,重複伯努利試驗。
一次拋一枚硬幣試驗,正面朝上發生的概率爲0.5,做10次實驗,求每次試驗發生正面朝上的硬幣個數:

test = np.random.binomial(1, 0.5, 10)
print(test)

輸出:[1 1 1 0 1 1 1 0 0 0]

例2: n>1時,多個樣本進行試驗:
一次拋5枚硬幣,每枚硬幣正面朝上概率爲0.5,做10次試驗,求每次試驗發生正面朝上的硬幣個數:

test = np.random.binomial(5, 0.5, 10)
print(test)

輸出:[1 5 5 2 4 2 3 3 2 3]

例3: size爲元組的形式時:
一次拋5枚硬幣,每硬幣正面朝上概率爲0.5,做10次試驗,求每次試驗發生正面朝上的硬幣個數:

test = np.random.binomial(5, 0.5, (10, 5))
print(test)

輸出二維數組(ndarray類型):

[[1 2 2 4 1]
 [2 5 3 4 3]
 [1 4 1 2 4]
 [3 1 1 3 1]
 [1 4 2 4 2]
 [0 1 3 2 2]
 [4 2 1 1 2]
 [2 5 3 2 3]
 [1 1 2 2 2]
 [3 2 1 4 2]]

例4: 一次拋2個硬幣,每枚硬幣拋到正反兩面的概率都是0.5,那麼兩個硬幣都是正面的概率是多少?發生一正一反的概率是多少?
顯然答案是0.25和0.5,試驗次數越大,越能接近理論概率:

test = sum(np.random.binomial(2, 0.5, 100000) == 2) / 100000
print(test)

輸出:0.24843

test = sum(np.random.binomial(2, 0.5, 100000) == 1) / 100000
print(test)

輸出:0.49938

發佈了128 篇原創文章 · 獲贊 32 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章