numpy学习笔记16: 1000 次独立随机游走实验(绘制其分布直方图,同时叠加理论正态分布曲线)
以下是这段代码(全部代码在最后)的详细分步解释,结合统计学原理和可视化技巧:
1. 代码功能概述
这段代码通过 1000 次独立随机游走实验,模拟粒子在直线上的运动轨迹,计算每次实验的最终位置,并绘制其分布直方图。同时叠加理论正态分布曲线,验证中心极限定理的应用。
2. 分步代码解析
(1) 参数设置
mu = 0 # 理论均值(对称随机游走的期望位置) n_steps = 1000 # 每次实验的步数 sigma = np.sqrt(n_steps) # 理论标准差 ≈ 31.62 n_simulations = 1000 # 实验次数
-
mu=0
:对称随机游走(左/右概率各 50%)的期望最终位置为 0。 -
sigma
计算:
(2) 模拟随机游走
final_positions = [np.sum(np.random.choice([-1, 1], n_steps)) for _ in range(n_simulations) ]
-
内部逻辑:
-
np.random.choice([-1,1], n_steps)
:生成包含 1000 个元素的数组,元素随机为-1
或1
。 -
np.sum(...)
:计算该次实验的最终位置(所有步长的代数和)。 -
列表推导式:重复 1000 次实验,生成包含 1000 个最终位置的列表。
-
-
示例结果:
final_positions = [12, -5, 3, ..., -18] # 1000 个整数
(3) 绘制直方图(模拟数据分布)
plt.hist(final_positions, bins=30, density=True, alpha=0.7, label='Simulated Data')
-
参数解析:
-
bins=30
:将数据范围划分为 30 个区间(柱状图的柱子数量)。 -
density=True
:将纵轴从频数转换为 概率密度(直方图总面积为 1)。 -
alpha=0.7
:设置柱子透明度为 70%,便于与理论曲线叠加对比。 -
label='Simulated Data'
:图例标签,标注为模拟数据。
-
(4) 生成理论正态分布曲线
from scipy.stats import normx = np.linspace(mu - 4*sigma, mu + 4*sigma, 100) # 生成横坐标范围 pdf = norm.pdf(x, mu, sigma) # 计算理论概率密度 plt.plot(x, pdf, 'r-', linewidth=2, label='Theoretical PDF') # 绘制红色曲线
-
np.linspace
:生成从 μ−4σμ−4σ 到 μ+4σμ+4σ 的等间隔数组,覆盖 99.99% 的数据范围。 -
norm.pdf
:计算理论正态分布概率密度:
(5) 图表美化与显示
plt.title("Random Walk Final Position Distribution") # 标题 plt.xlabel("Final Position") # 横轴标签 plt.ylabel("Probability Density") # 纵轴标签 plt.legend() # 显示图例 plt.show() # 渲染图像
-
输出效果:
-
蓝色直方图:模拟数据的分布。
-
红色曲线:理论正态分布 N(0,31.622)N(0,31.622)。
-
3. 统计学原理验证
(1) 中心极限定理(CLT)
-
核心结论:独立同分布随机变量的和趋近于正态分布。
-
在此代码中的应用:
-
尽管单步位移是离散的(-1 或 1),但 1000 步的总位移近似服从正态分布 N(0,1000)N(0,1000)。
-
(2) 参数匹配验证
-
理论均值:μ=0μ=0
4. 关键参数调整建议
(1) 增加模拟次数
n_simulations = 10_000 # 提高统计显著性,直方图更平滑
(2) 非对称步长概率
# 向右概率 60%,向左概率 40% steps = np.random.choice([-1, 1], size=n_steps, p=[0.4, 0.6]) mu_theory = n_steps * ( (-1)*0.4 + 1*0.6 ) # 理论均值 = 200 (当 n_steps=1000)
(3) 可变步长
# 步长为 -0.5 或 2,改变均值和方差 steps = np.random.choice([-0.5, 2], size=n_steps)
5. 应用场景
-
金融建模:模拟股票价格或汇率的随机波动。
-
物理模拟:研究微粒在液体中的扩散(布朗运动)。
-
算法测试:评估蒙特卡洛方法的收敛性。
6. 完整代码输出示例
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False# 模拟1000次随机游走(增强统计显著性)
mu = 0 # 理论均值(对称随机游走的期望位置)
n_steps = 1000 # 每次实验的步数
n_simulations = 1000 # 实验次数
final_positions = [np.sum(np.random.choice([-1, 1], n_steps))for _ in range(n_simulations)
]# 绘制直方图
plt.hist(final_positions, bins=30, density=True, alpha=0.7, label='Simulated Data')from scipy.stats import norm
sigma = np.sqrt(n_steps) # sqrt(1000) ≈ 31.62 # 理论标准差 ≈ 31.62
# 绘制理论曲线
x = np.linspace(mu - 4*sigma, mu + 4*sigma, 100) # 生成横坐标范围
pdf = norm.pdf(x, mu, sigma) # 计算理论概率密度
plt.plot(x, pdf, 'r-', linewidth=2, label='Theoretical PDF') # 绘制红色曲线plt.title("Random Walk Final Position Distribution") # 标题
plt.xlabel("Final Position") # 横轴标签
plt.ylabel("Probability Density") # 纵轴标签
plt.legend() # 显示图例
plt.show() # 渲染图像
总结
-
代码逻辑:通过多次独立实验生成最终位置分布,对比理论正态曲线。
-
核心验证:中心极限定理在随机游走中的体现。
-
扩展性:可调整步长、概率、步数等参数探索不同场景。
此代码不仅展示了 NumPy 和 Matplotlib 的高效应用,还通过可视化直观验证了统计学中的重要理论!