用「Python+統計學」進行數據探索分析

用「Python+統計學」進行數據探索分析

文末領取【本文代碼文件】

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

<code># 導入相關模塊/<code><code>import pandas as pd/<code><code>import numpy as np/<code><code>import matplotlib.pyplot as plt/<code><code>import seaborn as sns/<code><code>%matplotlib inline/<code><code>%config InlineBackend.figure_format = 'retina'/<code>

隨機數

計算機發明後,便產生了一種全新的解決問題的方式:使用計算機對現實世界進行統計模擬——該方法又稱為“蒙特卡洛方法(Monte Carlo method)”。

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

<code>np.random.random(size=5) # size表示生成隨機數的個數/<code>
<code>array([ 0.32392203, 0.3373342 , 0.51677112, 0.28451491, 0.07627541])/<code>

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

<code>np.random.randint(1, 10, size=5) # 生成5個1到9之間的隨機整數/<code>
<code>array([5, 6, 9, 1, 7])/<code>

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

<code>np.random.seed(123)/<code>

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

  • np.random.binomial

  • np.random.poisson

  • np.random.exponential

  • np.random.normal

二項分佈

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

用「Python+统计学」进行数据探索分析

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

<code>def plot_binomial(n,p):/<code><code> '''繪製二項分佈的概率質量函數'''/<code><code> sample = np.random.binomial(n,p,size=10000) # 產生10000個符合二項分佈的隨機數/<code><code> bins = np.arange(n+2) /<code><code> plt.hist(sample, bins=bins, align='left', normed=True, rwidth=0.1) # 繪製直方圖/<code><code> #設置標題和座標/<code><code> plt.title('Binomial PMF with n={}, p={}'.format(n,p)) /<code><code> plt.xlabel('number of successes')/<code><code> plt.ylabel('probability')/<code><code> plot_binomial(10, 0.5)/<code>
用「Python+统计学」进行数据探索分析

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

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

<code>fig = plt.figure(figsize=(12,4.5)) #設置畫布大小/<code><code>p1 = fig.add_subplot(121) # 添加第一個子圖/<code><code>plot_binomial(10, 0.2)/<code><code>p2 = fig.add_subplot(122) # 添加第二個子圖/<code><code>plot_binomial(10, 0.8)/<code>
用「Python+统计学」进行数据探索分析

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

泊松分佈

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

用「Python+统计学」进行数据探索分析

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

<code>lamb = 6/<code><code>sample = np.random.poisson(lamb, size=10000) # 生成10000個符合泊松分佈的隨機數/<code><code>bins = np.arange(20)/<code><code>plt.hist(sample, bins=bins, align='left', rwidth=0.1, normed=True) /<code><code># 繪製直方圖# 設置標題和座標軸/<code><code>plt.title('Poisson PMF (lambda=6)')/<code><code>plt.xlabel('number of arrivals')/<code><code>plt.ylabel('probability')/<code><code>plt.show/<code>
用「Python+统计学」进行数据探索分析

指數分佈

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

用「Python+统计学」进行数据探索分析

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

<code>tau = 10/<code><code>sample = np.random.exponential(tau, size=10000) # 產生10000個滿足指數分佈的隨機數/<code><code>plt.hist(sample, bins=80, alpha=0.7, normed=True) #繪製直方圖/<code><code>plt.margins(0.02)/<code>
<code># 根據公式繪製指數分佈的概率密度函數lam = 1 / tau/<code><code>x = np.arange(0,80,0.1)/<code><code>y = lam * np.exp(- lam * x)/<code><code>plt.plot(x,y,color='orange', lw=3)/<code>
<code>#設置標題和座標軸/<code><code>plt.title('Exponential distribution, 1/lambda=10')/<code><code>plt.xlabel('time')/<code><code>plt.ylabel('PDF')/<code><code>plt.show/<code>
用「Python+统计学」进行数据探索分析

正態分佈

正態分佈是一種很常用的統計分佈,可以描述現實世界的諸多事物,具備非常漂亮的性質

。其概率密度函數為:

用「Python+统计学」进行数据探索分析

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

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

身高、體重的分佈

以上從計算機模擬的角度出發,介紹了四種分佈,現在讓我們看一下現實中的數據分佈。我們查看身高和體重數據,看看他們是不是滿足正態分佈。

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

<code># 導入BRFSS數據/<code><code>import brfss/<code><code>df = brfss.ReadBrfss/<code><code>height = df.height.dropna/<code><code>weight = df.weight.dropna/<code>
<code>def plot_pdf_cdf(data, xbins, xrange, xlabel):/<code><code> '''繪製概率密度函數PDF和累積分佈函數CDF'''/<code><code> fig = plt.figure(figsize=(16,5)) # 設置畫布尺寸/<code>
<code> p1 = fig.add_subplot(121) # 添加第一個子圖/<code><code> # 繪製正態分佈PDF曲線/<code><code> std = data.std/<code><code> mean = data.mean/<code><code> x = np.arange(xrange[0], xrange[1], (xrange[1]-xrange[0])/100)/<code><code> y = norm_pdf(x, mean, std)/<code><code> plt.plot(x,y, label='normal distribution')/<code><code> # 繪製數據的直方圖/<code><code> plt.hist(data, bins=xbins, range=xrange, rwidth=0.9, /<code><code> alpha=0.5, normed=True, label='observables')/<code><code> # 圖片設置/<code><code> plt.legend/<code><code> plt.xlabel(xlabel)/<code><code> plt.title(xlabel +' PDF')/<code>
<code> p2 = fig.add_subplot(122) #添加第二個子圖/<code><code> # 繪製正態分佈CDF曲線/<code><code> sample = np.random.normal(mean, std, size=10000)/<code><code> plt.hist(sample, cumulative=True, bins=1000, range=xrange, /<code><code> normed=True, histtype='step', lw=2, label='normal distribution')/<code><code> # 繪製數據的CDF曲線/<code><code> plt.hist(data, cumulative=True, bins=1000, range=xrange, /<code><code> normed=True, histtype='step', lw=2, label='observables')/<code><code> #圖片設置/<code><code> plt.legend(loc='upper left')/<code><code> plt.xlabel(xlabel)/<code><code> plt.title( xlabel + ' CDF')/<code><code> plt.show/<code><code>人群的身高分佈比較符合正態分佈。/<code><code>plot_pdf_cdf(data=height, xbins=21, xrange=(1.2, 2.2), xlabel='height')/<code>
用「Python+统计学」进行数据探索分析

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

<code>plot_pdf_cdf(data=weight, xbins=60, xrange=(0,300), xlabel='weight')/<code>
用「Python+统计学」进行数据探索分析

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

<code>log_weight = np.log(weight)/<code><code>plot_pdf_cdf(data=log_weight, xbins=53, xrange=(3,6), xlabel='log weight')/<code>
用「Python+统计学」进行数据探索分析

End.

長按下方海報領取【本文代碼文件】

· 愛數據每週免費直播 ·

直播主題:疫情期間,入職崗位面試覆盤

直播內容:

  • 招聘、面試趨勢變化及應對策略

  • 電話面試/視頻面試有何要求

  • 大廠招聘需求、各城市需求變化

直播時間:3月26日 本週四晚20:30準時直播分享

用「Python+统计学」进行数据探索分析


分享到:


相關文章: