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

概率论是数据科学的基石,但很多初学者在面对"概率密度函数"、"累积分布"这些抽象概念时,常常陷入公式记忆的困境。本文将通过Python的NumPy和Matplotlib,带你用代码和可视化手段重新认识概率分布,让数学直觉从屏幕上自然生长出来。

1. 环境准备与基础概念

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

pip install numpy matplotlib scipy

概率分布分为离散型和连续型两大类:

  • 离散型 :取值可列举(如掷骰子的结果)
  • 连续型 :取值充满一个区间(如人的身高)

它们的核心区别在于:

  • 离散型用**概率质量函数(PMF)**描述
  • 连续型用**概率密度函数(PDF)**描述

关键理解:概率密度不是概率,它的积分才是。就像线密度不是质量,需要乘以长度才能得到质量。

2. 离散型分布可视化实战

让我们从最简单的伯努利分布开始。假设有一个不公平硬币,正面朝上的概率为0.7:

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

p = 0.7
x = [0, 1]
pmf = bernoulli.pmf(x, p)

plt.stem(x, pmf, use_line_collection=True)
plt.title('Bernoulli Distribution PMF (p=0.7)')
plt.xlabel('Outcome')
plt.ylabel('Probability')
plt.xticks(x, ['Tails', 'Heads'])
plt.show()

伯努利分布PMF

进阶到二项分布——n次独立伯努利试验的成功次数分布:

from scipy.stats import binom

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

plt.bar(x, pmf)
plt.title(f'Binomial Distribution PMF (n={n}, p={p})')
plt.xlabel('Number of successes')
plt.ylabel('Probability')
plt.show()

离散型分布的三个关键特征 :

  1. 每个点有明确的概率值
  2. 所有点概率之和为1
  3. CDF是右连续的阶梯函数

3. 连续型分布可视化解析

正态分布是最著名的连续型分布。让我们绘制它的PDF和CDF:

from scipy.stats import norm

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

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(x, pdf)
ax1.set_title('Normal Distribution PDF')
ax2.plot(x, cdf)
ax2.set_title('Normal Distribution CDF')
plt.show()

正态分布PDF和CDF

连续型分布的核心特性 :

  • PDF曲线下的总面积等于1
  • CDF是PDF的积分,单调递增
  • 单点概率为0,只有区间概率有意义

4. 概率分布的变换与可视化技巧

4.1 随机变量变换

当Y=g(X)时,如何求Y的分布?对于单调函数,我们可以使用变量替换法:

from scipy.stats import uniform

# 原始X分布:均匀分布
X = uniform(loc=0, scale=1)
x = np.linspace(0, 1, 1000)
pdf_x = X.pdf(x)

# Y = -log(X)变换
y = -np.log(x)
pdf_y = pdf_x / np.abs(-1/x)  # 变量替换公式

plt.figure(figsize=(10, 4))
plt.subplot(121)
plt.plot(x, pdf_x)
plt.title('Original X ~ Uniform(0,1)')
plt.subplot(122)
plt.plot(y, pdf_y)
plt.title('Transformed Y = -log(X)')
plt.tight_layout()
plt.show()

4.2 多维分布可视化

对于二维正态分布,我们可以用等高线和3D图来展示:

from scipy.stats import multivariate_normal
from mpl_toolkits.mplot3d import Axes3D

mu = [0, 0]
cov = [[1, 0.5], [0.5, 1]]
x, y = np.mgrid[-3:3:.1, -3:3:.1]
pos = np.dstack((x, y))
rv = multivariate_normal(mu, cov)

fig = plt.figure(figsize=(12, 5))
ax1 = fig.add_subplot(121)
ax1.contourf(x, y, rv.pdf(pos))
ax1.set_title('2D Contour Plot')

ax2 = fig.add_subplot(122, projection='3d')
ax2.plot_surface(x, y, rv.pdf(pos), cmap='viridis')
ax2.set_title('3D Surface Plot')
plt.show()

5. 实际应用案例:假设检验可视化

让我们用可视化方法理解p值的概念。假设我们有一组数据,想检验其均值是否为0:

np.random.seed(42)
data = np.random.normal(loc=0.5, scale=1, size=30)
t_stat, p_value = ttest_1samp(data, 0)

# 可视化
null_dist = t(df=len(data)-1)
x = np.linspace(-4, 4, 1000)
plt.plot(x, null_dist.pdf(x))
plt.axvline(t_stat, color='r', linestyle='--')
plt.fill_between(x[x>=abs(t_stat)], null_dist.pdf(x[x>=abs(t_stat)]), color='red', alpha=0.3)
plt.fill_between(x[x<=-abs(t_stat)], null_dist.pdf(x[x<=-abs(t_stat)]), color='red', alpha=0.3)
plt.title(f't-distribution with p-value={p_value:.3f}')
plt.xlabel('t-statistic')
plt.ylabel('Density')
plt.show()

假设检验可视化的关键点 :

  1. 绘制零假设下的理论分布
  2. 标记样本统计量的位置
  3. 着色表示更极端的区域(p值)

6. 交互式可视化进阶

静态图有时难以展示概率分布的动态特性。我们可以使用IPython的交互功能:

from ipywidgets import interact

def plot_normal(mean=0, std=1):
    x = np.linspace(-10, 10, 1000)
    pdf = norm.pdf(x, mean, std)
    plt.plot(x, pdf)
    plt.ylim(0, 0.5)
    plt.title(f'N(μ={mean}, σ={std})')
    plt.show()

interact(plot_normal, mean=(-5, 5), std=(0.1, 2.0))

这种交互式探索特别适合:

  • 理解参数变化对分布形态的影响
  • 演示中心极限定理
  • 比较不同分布之间的差异

7. 从可视化到蒙特卡洛模拟

可视化不仅能帮助我们理解,还能引导出强大的计算方法。比如计算复杂积分:

def f(x):
    return np.exp(-x**2) * np.sin(x)**2

x = np.linspace(-3, 3, 1000)
plt.plot(x, f(x), label='Integrand')
plt.fill_between(x, f(x), alpha=0.2)
plt.plot(x, norm.pdf(x), label='Normal PDF')
plt.legend()

# 蒙特卡洛积分
samples = np.random.normal(size=10000)
integral = np.mean(f(samples) / norm.pdf(samples))
print(f'Monte Carlo estimate: {integral:.4f}')

蒙特卡洛方法的三步可视化 :

  1. 绘制被积函数和目标分布
  2. 生成目标分布的随机样本
  3. 计算样本点的加权平均
Logo

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

更多推荐