python 二项分布_二项分布的理论基础、应用及Python实践
二項分布是概率統計中非常基礎、非常實用的一種分布,可以說它在我們的生活中無所不在。它說明了這樣一種現象:在給定的試驗次數中,某一結果會發生多少次。
比如:
這個月有多少天會刮北風?
今年有多少天會下雨?
經過一個路口100次,有多少次會是綠燈?
一年之中會有多少次出門就見狗?
伯努利分布伯努利分布是二項分布的基礎,它只有兩種狀態,比如拋硬幣的時候,結果只有正面和反面兩種情況,且兩種情況的概率之和為1。也就是說,當我們給定正面朝上的概率的時候,這個分布的一切就都確定了。
我們以0和1來標識這兩種可能的結果,那么其概率函數為:
那么其期望值為:
其方差為:
排列組合1. 排列
從n個對象中有序地挑選出r個對象,我們稱之為排列,我們用以下公式統計其可能產生的排列數:
2. 組合
考慮另一種情況,仍然是從n個對象中抽取r個對象,但是這次我們不考慮其順序,這種過程我們稱之為組合。我們用以下公式統計其可能產生的組合數:
可以看出,這是n選r的排列數除以r的排列數。上述公式又被稱作二項系數,通常用“n選r”表示。
3. Python計算
那么接下來我們用Python來寫一個函數,用來計算不同參數下的排列與組合的數量。在排列組合的計算中,我們可能會輸入兩個參數:總樣本量n、需要抽取的樣本數k。
那么我們就定義如下函數:
from functools import reducedef PC(n, k): """ 計算并返回排列組合數 """ # 非法輸入返回空 if n <= 0 or k < 0 or n < k: print('Wrong Input!') return None # k為0時,排列組合的情況恒為1 if k == 0: return 1, 1 # 生成正序及倒序的序列 series_asc = list(range(1, n+1)) series_desc = sorted(series_asc, reverse=True) # 排列 permutation = reduce(lambda x, y: x*y, series_desc[:k]) # 組合 perm2 = reduce(lambda x, y: x*y, series_asc[:k]) combination = int(permutation / perm2) return permutation, combination隨手測試幾個:
for n in range(1, 5): for k in range(1, 3): print('-'*10) print(n, k) print(PC(n, k))結果是正確的:
----------1 1(1, 1)----------1 2Wrong Input!None----------2 1(2, 2)----------2 2(2, 1)----------3 1(3, 3)----------3 2(6, 3)----------4 1(4, 4)----------4 2(12, 6)二項分布回顧伯努利分布的情況:一次實驗只有可能有兩種結果,分別用0和1來表示,其中結果1發生的概率為p。那么在n次獨立實驗中,不考慮順序的情況下,結果1出現k次的概率是多少?
首先,因為n次實驗相互獨立,所以根據乘法定律,任何一種結果1出現k次的場景發生的概率均為:
然后,我們需要考慮結果為1的次數剛好為k的情況有多少種。很明顯,這就是一個伯努利試驗的組合問題,n次實驗中有k次結果為1的情況共有“n選k”種,兩者相乘就是該事件發生的概率。
因此:
Python計算那么我們來用Python實現一個計算二項分布概率的小工具,在這里,我們的輸入參數包含總試驗次數n、正樣本發生的次數k以及正樣本發生的概率p:
def binominal_prob(n, k, p): """ 計算并返回二項分布中某結果發生的概率 """ # 任一k次成功的序列出現的概率 p_base = p ** k * (1-p) ** (n-k) # n次試驗中k次成功的組合數 # 直接用上邊我們編寫的排列組合函數來求解 combination = PC(n, k)[1] p_result = p_base * combination return p_result那么接下來,我們利用我們剛剛寫好的小工具,來看一下在10次試驗中,不同的概率對應的二項分布是什么樣的。
probs = [binominal_prob(10, i, 0.5) for i in range(11)]我們將結果畫出來看看:
%matplotlib inlineimport numpy as npimport matplotlib.pyplot as pltimport seaborn as snssns.set()probs = [round(i/10,1) for i in range(1, 10)]n = 20plt.figure(figsize=(16, 6))for p in probs: dist_probs = [binominal_prob(n, i, p) for i in range(n+1)] plt.plot(range(n+1), dist_probs, label='p={0}'.format(p))plt.legend()plt.title('Binominal Distributions of Different P value')plt.savefig('binominal.jpg')plt.show()或者我們使用交互式的繪圖庫plotly來嘗試同樣的事情:
import plotly.graph_objects as goprobs = [round(i/10,1) for i in range(1, 10)]n = 20fig = go.Figure()for p in probs: dist_probs = [binominal_prob(n, i, p) for i in range(n+1)] fig.add_trace(go.Scatter( x=list(range(n+1)), y=dist_probs, name='p={0}'.format(p) ))fig.show()可以看到,plotly實現的效果更加靚麗,且額外支持了動態交互,在這里我就選擇把p=0.8這條線隱藏了起來。
一個利用極大似然估計求二項分布概率參數的例子我們現在想象一種情況,有一枚分布不太均勻的硬幣,每次拋向空中后,落地為正面的概率為p,任意兩次實驗之間相互獨立。現在我們做了4次實驗,其中有三次正面朝上,那么請問p的值為多少?
我們之前曾經提到過極大似然估計,在這里我們用同樣的思路去估計p的取值。極大似然估計的思想就是尋找一個參數,使得當前結果發生的概率最大,那么我們先定義出來當前結果發生的概率公式:
對其求導并使導數為0,有:
可得,當p=0.75時,P(X=3)=0.422達到最大(另一個解p=0顯然不可能,因為硬幣朝上已經發生了,并不是“不可能事件”;另外考慮不同區間導數的取值也可以得到答案)。
- END -
文源網絡,僅供學習之用,如有侵權,聯系刪除。
往期精彩◆ ?50款開源工具你都用過嗎?
◆ ?python+C、C++混合編程的應用
◆ ?python網絡爬蟲的基本原理詳解
◆ ?Python自動操控excel,一小時解決你一天的工作
◆ ?如何用Python增強Excel,減少處理復雜數據的痛苦?
總結
以上是生活随笔為你收集整理的python 二项分布_二项分布的理论基础、应用及Python实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: input 0.1无法相加_你真的知道0
- 下一篇: 夜光神杯剧情介绍