利用python進行蒙特卡羅模擬

2021-01-14 數據皮皮俠

本文用Python統計模擬的方法,介紹四種常用的統計分布,包括離散分布:二項分布和泊松分布,以及連續分布:指數分布和正態分布,最後查看人群的身高和體重數據所符合的分布。


# 導入相關模塊import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns %matplotlib inline %config InlineBackend.figure_format = 'retina'



隨機數


計算機發明後,便產生了一種全新的解決問題的方式:使用計算機對現實世界進行統計模擬。該方法又稱為「蒙特卡洛方法(Monte Carlo method)」,起源於二戰時美國研製原子彈的曼哈頓計劃,它的發明人中就有大名鼎鼎的馮·諾依曼。蒙特卡洛方法的名字來源也頗為有趣,相傳另一位發明者烏拉姆的叔叔經常在摩洛哥的蒙特卡洛賭場輸錢,賭博是一場概率的遊戲,故而以概率為基礎的統計模擬方法就以這一賭城命名了。


使用統計模擬,首先要產生隨機數,在Python中,numpy.random 模塊提供了豐富的隨機數生成函數。比如生成0到1之間的任意隨機數:


np.random.random(size=5)  # size表示生成隨機數的個數


array([ 0.32392203,  0.3373342 ,  0.51677112,  0.28451491,  0.07627541])


又比如生成一定範圍內的隨機整數:


np.random.randint(1, 10, size=5)  # 生成5個1到9之間的隨機整數


array([5, 6, 9, 1, 7])


計算機生成的隨機數其實是偽隨機數,是由一定的方法計算出來的,因此我們可以按下面方法指定隨機數生成的種子,這樣的好處是以後重複計算時,能保證得到相同的模擬結果。


np.random.seed(123)


在NumPy中,不僅可以生成上述簡單的隨機數,還可以按照一定的統計分布生成相應的隨機數。這裡列舉了二項分布、泊松分布、指數分布和正態分布各自對應的隨機數生成函數,接下來我們分別研究這四種類型的統計分布。


np.random.binomial()

np.random.poisson()

np.random.exponential()

np.random.normal()



二項分布


二項分布是n個獨立的是/非試驗中成功的次數的概率分布,其中每次試驗的成功概率為p。這是一個離散分布,所以使用概率質量函數(PMF)來表示k次成功的概率:



最常見的二項分布就是投硬幣問題了,投n次硬幣,正面朝上次數就滿足該分布。下面我們使用計算機模擬的方法,產生10000個符合(n,p)的二項分布隨機數,相當於進行10000次實驗,每次實驗投擲了n枚硬幣,正面朝上的硬幣數就是所產生的隨機數。同時使用直方圖函數繪製出二項分布的PMF圖。


def plot_binomial(n,p):    '''繪製二項分布的概率質量函數'''    sample = np.random.binomial(n,p,size=10000)  # 產生10000個符合二項分布的隨機數    bins = np.arange(n+2)    plt.hist(sample, bins=bins, align='left', normed=True, rwidth=0.1)  # 繪製直方圖    #設置標題和坐標    plt.title('Binomial PMF with n={}, p={}'.format(n,p))      plt.xlabel('number of successes')    plt.ylabel('probability') plot_binomial(10, 0.5)



投10枚硬幣,如果正面或反面朝上的概率相同,即p=0.5, 那麼出現正面次數的分布符合上圖所示的二項分布。該分布左右對稱,最有可能的情況是正面出現5次。


但如果這是一枚作假的硬幣呢?比如正面朝上的概率p=0.2,或者是p=0.8,又會怎樣呢?我們依然可以做出該情況下的PMF圖。


fig = plt.figure(figsize=(12,4.5)) #設置畫布大小p1 = fig.add_subplot(121)  # 添加第一個子圖plot_binomial(10, 0.2) p2 = fig.add_subplot(122)  # 添加第二個子圖plot_binomial(10, 0.8)



這時的分布不再對稱了,正如我們所料,當概率p=0.2時,正面最有可能出現2次;而當p=0.8時,正面最有可能出現8次。



泊松分布


泊松分布用於描述單位時間內隨機事件發生次數的概率分布,它也是離散分布,其概率質量函數為:



比如你在等公交車,假設這些公交車的到來是獨立且隨機的(當然這不是現實),前後車之間沒有關係,那麼在1小時中到來的公交車數量就符合泊松分布。同樣使用統計模擬的方法繪製該泊松分布,這裡假設每小時平均來6輛車(即上述公式中lambda=6)。


lamb = 6sample = np.random.poisson(lamb, size=10000)  # 生成10000個符合泊松分布的隨機數bins = np.arange(20) plt.hist(sample, bins=bins, align='left', rwidth=0.1, normed=True) # 繪製直方圖# 設置標題和坐標軸plt.title('Poisson PMF (lambda=6)') plt.xlabel('number of arrivals') plt.ylabel('probability') plt.show()




指數分布


指數分布用以描述獨立隨機事件發生的時間間隔,這是一個連續分布,所以用質量密度函數表示:



比如上面等公交車的例子,兩輛車到來的時間間隔,就符合指數分布。假設平均間隔為10分鐘(即1/lambda=10),那麼從上次發車開始,你等車的時間就滿足下圖所示的指數分布。


tau = 10sample = np.random.exponential(tau, size=10000)  # 產生10000個滿足指數分布的隨機數plt.hist(sample, bins=80, alpha=0.7, normed=True) #繪製直方圖plt.margins(0.02) # 根據公式繪製指數分布的概率密度函數lam = 1 / tau x = np.arange(0,80,0.1) y = lam * np.exp(- lam * x) plt.plot(x,y,color='orange', lw=3)#設置標題和坐標軸plt.title('Exponential distribution, 1/lambda=10') plt.xlabel('time') plt.ylabel('PDF') plt.show()




正態分布


正態分布是一種很常用的統計分布,可以描述現實世界的諸多事物,具備非常漂亮的性質,我們在下一講參數估計之中心極限定理時會詳細介紹。其概率密度函數為:



以下繪製了均值為0,標準差為1的正態分布的概率密度曲線,其形狀好似一口倒扣的鐘,因此也稱鐘形曲線。


def norm_pdf(x,mu,sigma):    '''正態分布概率密度函數'''    pdf = np.exp(-((x - mu)**2) / (2* sigma**2)) / (sigma * np.sqrt(2*np.pi))    return pdf mu = 0    # 均值為0sigma = 1 # 標準差為1# 用統計模擬繪製正態分布的直方圖sample = np.random.normal(mu, sigma, size=10000) plt. hist(sample, bins=100, alpha=0.7, normed=True)# 根據正態分布的公式繪製PDF曲線x = np.arange(-5, 5, 0.01) y = norm_pdf(x, mu, sigma) plt.plot(x,y, color='orange', lw=3) plt.show()




身高、體重的分布


以上從計算機模擬的角度出發,介紹了四種分布,現在讓我們看一下現實中的數據分布。繼續上一講數據探索之描述性統計中使用的BRFSS數據集,我們查看其中的身高和體重數據,看看他們是不是滿足正態分布。


首先導入數據,並編寫繪製PDF和CDF圖的函數 plot_pdf_cdf(),便於重複使用。


# 導入BRFSS數據import brfss df = brfss.ReadBrfss() height = df.height.dropna() weight = df.weight.dropna()


def plot_pdf_cdf(data, xbins, xrange, xlabel):    '''繪製概率密度函數PDF和累積分布函數CDF'''    fig = plt.figure(figsize=(16,5)) # 設置畫布尺寸    p1 = fig.add_subplot(121)  # 添加第一個子圖    # 繪製正態分布PDF曲線    std = data.std()    mean = data.mean()    x = np.arange(xrange[0], xrange[1], (xrange[1]-xrange[0])/100)    y = norm_pdf(x, mean, std)    plt.plot(x,y, label='normal distribution')    # 繪製數據的直方圖    plt.hist(data, bins=xbins, range=xrange, rwidth=0.9,             alpha=0.5, normed=True, label='observables')    # 圖片設置    plt.legend()    plt.xlabel(xlabel)    plt.title(xlabel +' PDF')    p2 = fig.add_subplot(122)  #添加第二個子圖    # 繪製正態分布CDF曲線    sample = np.random.normal(mean, std, size=10000)    plt.hist(sample, cumulative=True, bins=1000, range=xrange,             normed=True, histtype='step', lw=2, label='normal distribution')    # 繪製數據的CDF曲線    plt.hist(data, cumulative=True, bins=1000, range=xrange,             normed=True, histtype='step', lw=2, label='observables')    #圖片設置    plt.legend(loc='upper left')    plt.xlabel(xlabel)    plt.title( xlabel + ' CDF')    plt.show()


人群的身高分布比較符合正態分布。


plot_pdf_cdf(data=height, xbins=21, xrange=(1.2, 2.2), xlabel='height')



但是體重分布明顯右偏,與對稱的正態分布存在一定的差異。


plot_pdf_cdf(data=weight, xbins=60, xrange=(0,300), xlabel='weight')



將體重數據取對數值後,其分布就與正態分布非常吻合。


log_weight = np.log(weight) plot_pdf_cdf(data=log_weight, xbins=53, xrange=(3,6), xlabel='log weight')



參考資料:


相關焦點

  • 蒙特卡羅模擬法
    蒙特卡羅模擬法蒙特卡羅模擬法是一種使用隨機數和概率來解決問題的計算方法,它又稱隨機抽樣或統計試驗法,整體思路是(模擬——抽樣——估值),工作原理是不斷抽樣、逐漸逼近。通俗說就是建立一個模型用來模擬某事件,然後不斷隨機取樣,進行很多次實驗後,得出一個接近真實值的估值。
  • 蒙特卡洛模擬(Python)深入教程
    字幕組雙語原文:蒙特卡洛模擬(Python)深入教程英語原文:Monte Carlo Simulation An In-depth Tutorial with Python翻譯:大表哥、wiige什麼是蒙特卡羅模擬?
  • 蒙特卡羅方法及應用
    ,起源於早期的用機率近似概率的數學思想,它利用隨機數進行統計試驗,以求得的統計特徵值( 如均值、概率等) 作為待解問題的數值解。所以, 在現代計算機技術出現之前, 用頻率近似概率的方法——抑或稱為雛形時代的蒙特卡羅方法——並沒有得到實質上的應用。若用數值模擬方法代替上述的真正的投針試驗, 是利用均勻分布於(0,1) 之間的隨機數序列, 並構造出隨機投針的數學模型, 然後進行大量的隨機統計並求得π的近似值。
  • 人工智慧之蒙特卡羅方法(MCM)
    3)建立各種估計量  構造了概率模型並能從中抽樣後,即實現模擬實驗後,就要確定一個隨機變量,作為所要求的問題的解,稱它為無偏估計。建立各種估計量,相當於對模擬實驗的結果進行考察和登記,從中得到問題的解。  通常蒙特卡羅方法通過構造符合一定規則的隨機數來解決各種實際問題。
  • 蒙特卡羅方法-布豐投針試驗的概率
    布豐投針實驗是第一個用幾何形式表達概率問題的例子,值得一提的是,他採用的方法是設計一個適當的試驗,這個試驗是以概率為原理的,而這個概率的數值與我們感興趣的一個量(如)又有關,於是就利用試驗結果來估計這個量。這個方法隨著計算機等現代技術的發展,已經發展成為具有廣泛應用性的蒙特卡羅方法。蒙特卡羅方法也稱為統計模擬法、隨機抽樣技術,是一種隨機模擬方法。
  • 蒙特卡羅方法入門
    它誕生於上個世紀40年代美國的"曼哈頓計劃",名字來源於賭城蒙特卡羅,象徵概率。 二、π的計算 第一個例子是,如何用蒙特卡羅方法計算圓周率π。通過R語言腳本隨機模擬30000個點,π的估算值與真實值相差0.07%。 三、積分的計算 上面的方法加以推廣,就可以計算任意一個積分的值。
  • 歷史模擬法、蒙特卡羅的模擬法計算VaR和ES值!
    歷史模擬法、蒙特卡羅的模擬法計算VaR和ES值! 一、知識點介紹1.1 歷史模擬法我們在之前有用到Delta-Normal的GARCH和RiskMetrics方法來計算aR和ES,假設的是殘差滿足正態分布,對殘差進行二次相關序列的建模並擬合殘差,能夠得到未來的預測值。
  • 蒙特卡洛模擬方法
    但是會用python去構思基本的東西出來。我希望此文可以記錄思想,整理筆記、知識,並將其中承載的價值傳播給他人。 在本文中您可以學習到以下幾點知識蒙特卡洛定積分算法原理講解(公式篇)python實現算法(代碼篇)蒙特卡洛算法起源       蒙特卡羅方法於20世紀40年代美國在第二次世界大戰中研製原子彈的「曼哈頓計劃」計劃的成員S.M.烏拉姆和J.馮·諾伊曼首先提出。
  • 蒙特卡羅方法在靈敏度分析中的應用及其優勢
    總體而言,我們在以下方面利用敏感性分析: l 對分配變量的輸入值變化影響數學模型結果的級別進行分類。   靈敏度分析中的蒙特卡羅方法 在當今的電子和工程領域,使用數學工具進行敏感性分析很普遍,我們將這些工具分為兩類: l
  • 由於量子的波粒二象性,​許多量子材料幾乎不能進行數學模擬
    許多量子材料幾乎不可能進行數學模擬,因為所需的計算時間太長。現在,柏林自由大學和柏林亥姆霍茲中心(HZB)的一個聯合研究小組,已經展示了一種顯著減少計算時間的方法,這可能會加速未來節能IT技術材料的開發。超級計算機對於探索複雜的研究問題至關重要,理論上,即使是新材料也可以在計算機中進行模擬,以計算它們的磁學和熱學性質以及相變。
  • 用Python入門不明覺厲的馬爾可夫鏈蒙特卡羅(附案例代碼)
    在這裡,β (beta) 和 α (alpha) 是模型的參數,我們只能通過MCMC去模擬它們的值。下面展示了一個參數變化的logistic函數。馬爾可夫鏈蒙特卡洛馬爾可夫鏈蒙特卡羅是一組從概率分布中抽樣
  • Python學習第130課——蒙特卡洛模擬隨機遊走
    【每天幾分鐘,從零入門python編程的世界!】之前我們用代碼實現了醉漢隨機遊走的過程。現在我們用蒙特卡洛模擬計算一下,醉漢在不同的條件下打車回家的概率。我們先定義幾個參數。how_many_simulations,表示我們模擬多少次醉漢遊走的過程。taking_a_taxi_counter,表示我們模擬醉漢遊走一定的次數後,統計打車回家的次數。注意:我們以後寫代碼要把程序中需要的參數都變量化,就是說要先聲明需要的變量,用變量保存需要的參數。
  • Python語言程序設計筆記——第四周圓周率計算,質數求和
    圓周率計算方法:近似公式,蒙特卡羅方法1.\ 4/(8*k+1) – 2/(8*k+4) - \ 1/(8*k+5) – 1/(8*k+6))print("圓周率值是: {}".format(pi))>>>圓周率值是: 3.141592653589793python
  • 基於蒙特卡羅方法的速率分布函數演化過程研究
    蒙特卡羅方法生成三維理想氣體麥克斯韋分布[J]. 大學物理,2018,37(3): 63-68MO Y Y, LI S Z. Generating three-dimensional Maxwell distribution using Monte Carlo method[J]. College Physics, 2018, 37(3): 63-68.
  • 跟著Sutton經典教材學強化學習中的蒙特卡羅方法
    好消息是,蒙特卡羅方法能解決以上問題!蒙特卡羅是一種估計複雜的概率分布的經典方法。本文部分內容取自Sutton的經典教材《強化學習》,並提供了額外的解釋和例子。初探蒙特卡羅蒙特卡羅模擬以摩納哥的著名賭場命名,因為機會和隨機結果是建模技術的核心,它們與輪盤賭,骰子和老虎機等遊戲非常相似。相比於動態規劃,蒙特卡羅方法以一種全新的方式看待問題,它提出了這個問題:我需要從環境中拿走多少樣本去鑑別好的策略和壞的策略?
  • 研究提高量子色動力學模擬精度!基本粒子如何相互作用?
    本文參加百家號科學#了不起的基礎科學#系列徵文在過去的幾十年裡,計算機能力的指數級增長,以及隨之而來的算法質量提高,使得理論物理學家和粒子物理學家能夠對基本粒子及其相互作用進行更複雜、更精確的模擬。如果在模擬中增加晶格點的數量,就很難區分模擬的觀測結果與周圍噪聲之間的差別。德國美因茨亥姆霍茲研究所的物理學家馬可·切(Marco Ce)現在在EPJ Plus上發表了一項新研究:描述了一種模擬「大」粒子群的技術(至少以粒子物理學的標準來看)。提高了信噪比,提高了模擬精度;至關重要的是,還可以用來模擬重子的整體:包括構成原子核的質子和中子在內的一類基本粒子。
  • 利用python做t檢驗
    >T檢驗:使用前提:       當樣本符合正態分布或趨近於正太分布時可以使用;(根據中心極限定理,當樣本n>30時,可認為近似符合正態分布)使用用途:檢驗的總體方差未知,主要檢驗單個樣本是否和已知的總體均值相等;(python
  • 利用python計算三角形的面積
    利用python計算三角形的面積。(1)輸入三個數,作為三角形的三個邊長,利用海倫公式計算三角形的面積。海倫公式:假設在平面內,有一個三角形,邊長分別為 a、b、c,三角形的面積 S可由以下公式求得。請對第 1 題進行改進,加上判斷三角形能否構成的條件,當輸入的三條邊不能構成三角形時提示「輸入的邊構不成三角形,請重新輸入!」,直到輸入合法才求解三角形的面積。完成後,將程序提交。
  • 利用Python來識別並提取圖片中文字
    文字識別是利用計算機自動識別字符的技術,是模式識別應用的一個重要領域。文字識別一般包括文字信息的採集、信息的分析與處理、信息的分類判別等幾個部分。在文字識別中,許多應用軟體可以幫我們忙,那麼強大的python可以實現圖片中的文字識別嗎?    在學習python的圖像識別中,我們了解到關於中文的識別,效果比較好而且開源的應該就是Tesseract-OCR了,python裡面也有一個包去使用Tesseract-OCR,這個包叫pytesseract。
  • python利用海倫公式求三角形的面積
    海倫公式又譯作希倫公式、海龍公式、希羅公式等,它是利用三角形的三條邊的邊長直接求三角形面積的公式,表達式為:其中p是三條邊的和的一半兒。 python根據三角形三條邊求面積1.三角形的三條邊的符合條件我們知道,三角形有三條邊,且三條邊需要滿足兩邊之和大於第三邊,否則不構成三角形。