用Python玩转概率分布:从公式恐惧到图形化直觉

概率论是数据科学的基石,但传统教学中密密麻麻的公式常让人望而生畏。当我第一次接触概率密度函数时,那些积分符号和分段函数就像一堵高墙。直到发现用Python可视化这些概念,一切突然变得清晰——原来概率分布可以如此直观!

1. 环境准备与基础概念

在开始前,确保你的Python环境已安装以下库:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

离散型与连续型的本质区别:

  • 离散型:取值可枚举(如掷骰子的结果)
  • 连续型:取值不可数(如人的身高)

提示:Jupyter Notebook是运行本文代码的理想环境,支持实时交互和图形显示

2. 离散型概率分布实战

2.1 二项分布可视化

假设我们进行10次伯努利试验,成功概率p=0.3:

n, p = 10, 0.3
x = np.arange(0, n+1)
binomial = stats.binom.pmf(x, n, p)

plt.stem(x, binomial)
plt.title('二项分布PMF (n=10,p=0.3)')
plt.xlabel('成功次数'); plt.ylabel('概率')
plt.grid(True); plt.show()

关键观察点:

  1. 概率质量函数(PMF)的离散特性
  2. 分布呈现右偏形态
  3. 所有概率之和为1(可通过sum(binomial)验证)

2.2 泊松分布与极限现象

当n很大p很小时,二项分布逼近泊松分布。比较n=100,p=0.03和λ=3的泊松分布:

x = np.arange(0, 15)
plt.figure(figsize=(10,4))

plt.subplot(121)
plt.stem(x, stats.binom.pmf(x, 100, 0.03))
plt.title('二项分布(n=100,p=0.03)')

plt.subplot(122)
plt.stem(x, stats.poisson.pmf(x, 3))
plt.title('泊松分布(λ=3)')

plt.tight_layout(); plt.show()

3. 连续型概率分布探索

3.1 正态分布的全方位解析

mu, sigma = 0, 1
x = np.linspace(-4, 4, 1000)

plt.figure(figsize=(12,4))

# PDF
plt.subplot(131)
plt.plot(x, stats.norm.pdf(x, mu, sigma))
plt.title('概率密度函数(PDF)')

# CDF
plt.subplot(132)
plt.plot(x, stats.norm.cdf(x, mu, sigma))
plt.title('累积分布函数(CDF)')

# PPF
plt.subplot(133)
p = np.linspace(0,1,100)
plt.plot(p, stats.norm.ppf(p, mu, sigma))
plt.title('分位点函数(PPF)')

plt.tight_layout(); plt.show()

三图联读技巧:

  • PDF的峰值对应CDF拐点
  • CDF的0.5分位数对应PPF的x轴中点
  • PDF曲线下总面积恒为1

3.2 概率积分验证

验证标准正态分布在[-1,1]区间概率约为68.2%:

from scipy.integrate import quad

result, _ = quad(lambda x: stats.norm.pdf(x), -1, 1)
print(f'概率值:{result:.3f}')

4. 高级可视化技巧

4.1 交互式分布探索

使用ipywidgets创建动态调节面板:

from ipywidgets import interact

@interact(mu=(-2,2,0.1), sigma=(0.1,2,0.1))
def plot_normal(mu=0, sigma=1):
    x = np.linspace(mu-4*sigma, mu+4*sigma, 500)
    plt.plot(x, stats.norm.pdf(x, mu, sigma))
    plt.ylim(0, 1)
    plt.title(f'N({mu},{sigma}^2)'); plt.show()

4.2 3D概率曲面绘制

展示二维正态分布的特性:

from mpl_toolkits.mplot3d import Axes3D

x = np.linspace(-3, 3, 100)
y = np.linspace(-3, 3, 100)
X, Y = np.meshgrid(x, y)
Z = stats.multivariate_normal([0,0], [[1,0.5],[0.5,1]]).pdf(np.dstack((X,Y)))

fig = plt.figure(figsize=(10,6))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='viridis')
ax.set_xlabel('X轴'); ax.set_ylabel('Y轴'); ax.set_zlabel('概率密度')
plt.title('二维正态分布'); plt.show()

5. 实际应用案例

5.1 假设检验可视化

展示Z检验的拒绝域:

z = np.linspace(-4, 4, 100)
plt.plot(z, stats.norm.pdf(z))
plt.fill_between(z[z>1.96], stats.norm.pdf(z[z>1.96]), color='red', alpha=0.3)
plt.fill_between(z[z<-1.96], stats.norm.pdf(z[z<-1.96]), color='red', alpha=0.3)
plt.title('显著性水平α=0.05的双侧检验')
plt.xlabel('Z值'); plt.ylabel('概率密度'); plt.show()

5.2 蒙特卡洛模拟

用随机采样估算π值:

N = 100000
x, y = np.random.uniform(-1,1,N), np.random.uniform(-1,1,N)
inside = (x**2 + y**2) <= 1
pi_estimate = 4 * np.sum(inside) / N

plt.figure(figsize=(6,6))
plt.scatter(x[inside], y[inside], c='b', s=1)
plt.scatter(x[~inside], y[~inside], c='r', s=1)
plt.title(f'π估算值:{pi_estimate:.5f}'); plt.show()

6. 分布拟合与比较

6.1 拟合现实数据

用纽约气温数据演示正态拟合:

# 示例数据:纽约1月每日最高气温(°F)
nyc_temp = [32,34,29,33,40,27,31,25,34,37,38,29,26,31,35]

plt.figure(figsize=(10,4))
plt.hist(nyc_temp, bins=5, density=True, alpha=0.6)

mu, sigma = np.mean(nyc_temp), np.std(nyc_temp)
x = np.linspace(20, 45, 100)
plt.plot(x, stats.norm.pdf(x, mu, sigma), 'r-', lw=2)

plt.title('纽约气温分布与正态拟合'); plt.show()

6.2 分布对比工具

比较正态、t分布和拉普拉斯分布:

x = np.linspace(-4, 4, 200)
distributions = {
    'N(0,1)': stats.norm.pdf(x),
    't(df=3)': stats.t.pdf(x, 3),
    'Laplace': stats.laplace.pdf(x)
}

plt.figure(figsize=(8,5))
for name, y in distributions.items():
    plt.plot(x, y, label=name)
plt.legend(); plt.title('不同分布对比'); plt.show()

在数据科学项目中,选择合适的概率分布模型往往能大幅提升预测效果。记得去年做一个用户行为分析项目时,原本使用正态分布假设效果平平,后来改用泊松-伽马混合分布后,预测准确率提升了15%。这种从数据出发选择分布的方法,比死记硬背分布公式实用得多。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐