Python隨機采樣及概率分佈(二)

前言:

之前的《Python中的隨機采樣和概率分佈》我們介紹瞭Python中最簡單的隨機采樣函數。接下來我們更進一步,來看看如何從一個概率分佈中采樣,我們以幾個機器學習中最常用的概率分佈為例。

1. 二項(binomial)/伯努利(Bernoulli)分佈

1.1 概率質量函數(pmf)

二項分佈P(X=x; n, p)可以表示進行獨立重復試驗n次,每次有兩成功和失敗可能結果(分別對應概率p和1−p),共成功x次的概率。

1.2 函數原型

random.binomial(n, p, size=None)

參數:

n: int or array_like of ints   對應分佈函數中的參數 n,>=0,浮點數會被截斷為整形。
p: float or array_like of floats   對應分佈函數參數p, >=0並且<=1。
size: int or tuple of ints, optional   如果給定形狀為(m,n,k),那麼m×n×k個隨機樣本會從中抽取。默認為None,即返回一個一個標量隨機樣本。

返回:

out: ndarray or scalar  從帶參數的概率分佈中采的隨機樣本,每個樣本表示獨立重復實驗n次中成功的次數。

1.3 使用樣例

設進行獨立重復實驗10次,每次成功概率為0.5,采樣樣本表示總共的成功次數(相當於扔10次硬幣,正面朝上的次數)。總共采20個樣本。

import numpy as np
n, p = 10, .5  
s = np.random.binomial(n, p, 20)
print(s) # [4 5 6 5 4 2 4 6 7 2 4 4 2 4 4 7 6 3 5 6]

可以粗略的看到,樣本幾乎都在5周圍上下波動。
我們來看一個有趣的例子。一傢公司鉆瞭9口井,每口井成功的概率為0.1,所有井都失敗瞭,發生這種情況的概率是多少?
我們總共采樣2000次,來看下產生0結果的概率。

s = sum(np.random.binomial(9, 0.1, 20000) == 0)/20000.
print(s) # 0.3823

可見,所有井失敗的概率為0.3823,這個概率還是蠻大的。

2. 多項(multinomial)分佈

2.1 概率質量函數(pmf)

也就是說,多項分佈式二項分佈的推廣:仍然是獨立重復實驗n次,但每次不隻有成功和失敗兩種結果,而是k種可能的結果,每種結果的概率為pi。多項分佈是一個隨機向量的分佈,x=(x1,x2,…,xk)意為第i種結果出現xi次,P(X=x; n, p)也就表示第i種結果出現xi次的概率。

2.2 函數原型

random.multinomial(n, pvals, size=None)

參數:

n: int   對應分佈函數中的參數 n。
pvals: sequence of floats   對應分佈函數參數p, 其長度等於可能的結果數k,並且有0⩽pi⩽1。
size: int or tuple of ints, optional   為輸出形狀大小,因為采出的每個樣本是一個隨機向量,默認最後一維會自動加上k,如果給定形狀為(m,n),那麼m×n個維度為k的隨機向量會從中抽取。默認為None,即返回一個一個k維的隨機向量。

返回:

out: ndarray   從帶參數的概率分佈中采的隨機向量,長度為可能的結果數k,如果沒有給定 size,則shape為 (k,)。

2.3 使用樣例

設進行獨立重復實驗20次,每次情況的概率為1/6,采樣出的隨機向量表示每種情況出現次數(相當於扔20次六面骰子,點數為0, 1, 2, …, 5出現的次數)。總共采1個樣本。

s = np.random.multinomial(20, [1/6.]*6, size=1)
print(s) # [[4 2 2 3 5 4]]

當然,如果不指定size,它直接就會返回一個一維向量瞭

s = np.random.multinomial(20, [1/6.]*6)
print(s) # [4 1 4 3 5 3]

如果像進行多次采樣,改變 size即可:

s = np.random.multinomial(20, [1/6.]*6, size=(2, 2))
print(s)
# [[[4 3 4 2 6 1]
#   [5 2 1 6 3 3]]

#  [[5 4 1 1 6 3]
#   [2 5 2 5 4 2]]]

這個函數在論文<sup>[1]</sup>的實現代碼<sup>[2]</sup>中用來設置每一個 client分得的樣本數:

for cluster_id in range(n_clusters): 
    weights = np.random.dirichlet(alpha=alpha * np.ones(n_clients))
    clients_counts[cluster_id] = np.random.multinomial(clusters_sizes[cluster_id], weights)
    # 一共扔clusters_sizes[cluster_id]次篩子,該函數返回骰子落在某個client上各多少次,也就對應著該client應該分得的樣本數

3.均勻(uniform)分佈

3.1 概率密度函數(pdf)

均勻分佈可用於隨機地從連續區間[a,b)內進行采樣。

3.2 函數原型

random.uniform(low=0.0, high=1.0, size=None)

參數:

low: float or array_like of floats, optional   對應分佈函數中的下界參數 a,默認為0。
high: float or array_like of floats   對應分佈函數中的下界參數 b,默認為1.0。
size: int or tuple of ints, optional   為輸出形狀大小,如果給定形狀為(m,n,k),那麼m×n×k的樣本會從中抽取。默認為None,即返回一個單一標量。

返回:

out: ndarray or scalar   從帶參數的均勻分佈中采的隨機樣本

3.3 使用樣例

s = np.random.uniform(-1,0,10)
print(s)
# [-0.9479594  -0.86158902 -0.63754099 -0.0883407  -0.92845644 -0.11148294
#  -0.19826197 -0.77396765 -0.26809953 -0.74734785]

4. 狄利克雷(Dirichlet)分佈

4.1 概率密度函數(pdf)

P(x;α)∝∏i=1kxαi−1ix=(x1,x2,...,xk),xi>0,∑i=1kxi=1α=(α1,α2,...,αk).αi>0

4.2 函數原型

random.dirichlet(alpha, size=None)

參數:
alpha: sequence of floats, length k   對應分佈函數中的參數向量 α,長度為k。
size: int or tuple of ints, optional   為輸出形狀大小,因為采出的每個樣本是一個隨機向量,默認最後一維會自動加上k,如果給定形狀為(m,n),那麼m×n個維度為k的隨機向量會從中抽取。默認為None,即返回一個一個k維的隨機向量。

返回:

out: ndarray   采出的樣本,大小為(size,k)。

4.3 使用樣例

設α=(10,5,3)(意味著k=3),size=(2,2),則采出的樣本為2×2個維度為k=3的隨機向量。

s = np.random.dirichlet((10, 5, 3), size=(2, 2))
print(s)
# [[[0.82327647 0.09820451 0.07851902]
#   [0.50861077 0.4503409  0.04104833]]

#  [[0.31843167 0.22436547 0.45720285]
#   [0.40981943 0.40349597 0.1866846 ]]]

這個函數在論文[1]的實現代碼[2]中用來生成符合狄利克雷分佈的權重向量

for cluster_id in range(n_clusters): 
    # 為每個client生成一個權重向量,文章中分佈參數alpha每一維都相同
    weights = np.random.dirichlet(alpha=alpha * np.ones(n_clients))
    clients_counts[cluster_id] = np.random.multinomial(clusters_sizes[cluster_id], weights)

到此這篇關於Python隨機采樣及概率分佈(二)的文章就介紹到這瞭,更多相關Python隨機采樣及概率分佈內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: