卡方分佈和 Zipf 分佈模擬及 Seaborn 視覺化教程

小万哥丶發表於2024-06-04

卡方分佈

簡介

卡方分佈是一種連續機率分佈,常用於統計學中進行假設檢驗。它描述了在獨立抽樣中,每個樣本的平方偏差之和的分佈。卡方分佈的形狀由其自由度 (df) 引數決定,自由度越大,分佈越平緩。

引數

卡方分佈用兩個引數來定義:

df:自由度,表示卡方分佈的形狀。自由度必須為正整數。
size:輸出陣列的形狀。

公式

卡方分佈的機率密度函式 (PDF) 為:

f(x) = (x^(df/2 - 1) * np.exp(-x/2)) / (2^(df/2) * Gamma(df/2))    for x >= 0

其中:

f(x):表示在 x 點的機率密度。
x:非負實數。
df:自由度。
np.exp(-x/2):指數函式。
Gamma(df/2):伽馬函式。

生成卡方分佈資料

NumPy 提供了 random.chisquare() 函式來生成服從卡方分佈的隨機數。該函式接受以下引數:

df:自由度。
size:輸出陣列的形狀。

示例:生成 10 個自由度為 5 的卡方分佈隨機數:

import numpy as np

data = np.random.chisquare(df=5, size=10)
print(data)

視覺化卡方分佈

Seaborn 庫提供了便捷的函式來視覺化分佈,包括卡方分佈。

示例:繪製 1000 個自由度為 5 的卡方分佈隨機數的分佈圖:

import seaborn as sns
import numpy as np

data = np.random.chisquare(df=5, size=1000)
sns.distplot(data)
plt.show()

練習

  1. 模擬 20 個自由度為 10 的卡方分佈隨機數,並繪製它們的分佈圖。
  2. 比較不同自由度下卡方分佈形狀的變化。
  3. 利用卡方分佈來進行卡方檢驗,假設某枚硬幣是公平的,即正面朝上的機率為 0.5。拋擲硬幣 100 次,並計算正面朝上的次數是否服從二項分佈。

解決方案

import seaborn as sns
import numpy as np
from scipy import stats

# 1. 模擬隨機數並繪製分佈圖
data = np.random.chisquare(df=10, size=20)
sns.distplot(data)
plt.show()

# 2. 比較不同自由度下分佈形狀的變化
df_values = [2, 5, 10, 20]
for df in df_values:
    data = np.random.chisquare(df=df, size=1000)
    sns.distplot(data, label=f"df={df}")
plt.legend()
plt.show()

# 3. 進行卡方檢驗
heads = np.random.binomial(n=100, p=0.5)
chi2_stat, p_value = stats.chisquare(heads, f_exp=50)
print("卡方統計量:", chi2_stat)
print("p 值:", p_value)

# 由於 p 值大於 0.05,無法拒絕原假設,即可以認為硬幣是公平的。

瑞利分佈

簡介

瑞利分佈是一種連續機率分佈,常用於描述訊號處理和雷達系統中的幅度分佈。它表示在一個隨機變數的平方根服從指數分佈時,該隨機變數的分佈。

引數

瑞利分佈用一個引數來定義:

scale:尺度引數,控制分佈的平坦程度。較大的尺度引數使分佈更加平坦,兩側尾部更加分散。預設為 1。

公式

瑞利分佈的機率密度函式 (PDF) 為:

f(x) = (x scale) / (scale^2 np.exp(-x^2 / (2 scale^2)))    for x >= 0

其中:

f(x):表示在 x 點的機率密度。
x:非負實數。
scale:尺

Zipf分佈

簡介

Zipf分佈,又稱為Zeta分佈,是一種離散機率分佈,常用於描述自然語言、人口統計學、城市規模等領域中具有冪律特徵的資料分佈。它體現了“少數服從多數”的現象,即排名越靠前的元素出現的頻率越高。

引數

Zipf分佈用一個引數來定義:

a:分佈引數,控制分佈的形狀。a越小,分佈越偏向於少數元素,越接近冪律分佈。預設為 2。

公式

Zipf分佈的機率質量函式 (PMF) 為:

P(k) = 1 / (k ^ a)    for k >= 1

其中:

P(k):表示第 k 個元素出現的機率。
k:元素的排名,從 1 開始。
a:分佈引數。

生成Zipf分佈資料

NumPy提供了random.zipf()函式來生成服從Zipf分佈的隨機數。該函式接受以下引數:

a:分佈引數。
size:輸出陣列的形狀。

示例:生成10個服從Zipf分佈的隨機數,分佈引數為2:

import numpy as np

data = np.random.zipf(a=2, size=10)
print(data)

視覺化Zipf分佈

Seaborn庫提供了便捷的函式來視覺化分佈,包括Zipf分佈。

示例:繪製1000個服從Zipf分佈的隨機數的分佈圖,分佈引數為2:

import seaborn as sns
import numpy as np

data = np.random.zipf(a=2, size=1000)
sns.distplot(data)
plt.show()

練習

  1. 模擬不同分佈引數下Zipf分佈形狀的變化。
  2. 利用Zipf分佈來模擬一個城市的規模分佈,並計算排名前10的城市人口占總人口的比例。
  3. 比較Zipf分佈與冪律分佈的異同。

解決方案

import seaborn as sns
import numpy as np

# 1. 模擬不同分佈引數下Zipf分佈形狀的變化
a_values = [1.5, 2, 2.5, 3]
for a in a_values:
    data = np.random.zipf(a=a, size=1000)
    sns.distplot(data, label=f"a={a}")
plt.legend()
plt.show()

2. 模擬城市規模分佈並計算人口比例

population = np.random.zipf(a=2, size=100)
top10_population = population[:10].sum()
total_population = population.sum()
print("排名前10的城市人口:", top10_population)
print("排名前10的城市人口比例:", top10_population / total_population)

3. Zipf分佈與冪律分佈的比較

Zipf分佈和冪律分佈都描述了“少數服從多數”的現象,即排名越靠前的元素出現的頻率越高。

但是,Zipf分佈的引數化程度更高,可以更精確地描述不同領域的冪律現象。冪律分佈則更通用,但缺乏Zipf分佈對引數的控制能力。

具體來說,Zipf分佈的PMF為:

P(k) = 1 / (k ^ a)

冪律分佈的PMF為:

P(k) = C / k ^ alpha

其中,C為歸一化常數。

可見,Zipf分佈的引數a控制了分佈的傾斜程度,而冪律分佈的引數alpha則控制了分佈的整體形狀。

此外,Zipf分佈通常用於描述離散資料,而冪律分佈則可以用於描述離散和連續資料。

最後

為了方便其他裝置和平臺的小夥伴觀看往期文章:

微信公眾號搜尋:Let us Coding,關注後即可獲取最新文章推送

看完如果覺得有幫助,歡迎點贊、收藏、關注

相關文章