如何绘制派生概率密度函数?Python随机变量函数PDF可视化方法咨询
如何在Python中绘制派生随机变量的概率密度函数(PDF)
我来帮你梳理下在Python里处理这类问题的方法,不管是单变量变换还是多变量的情况,都有实用的实现方式,咱们一步步来:
一、单变量变换:以Y=X²为例
方法1:解析推导+直接计算
如果能从X的PDF推导出Y的PDF公式,那直接计算绘制是最准确的。对于Y=X²这个变换,因为X取正数和负数都能得到同一个Y值,所以根据随机变量变换的规则,Y的PDF公式是:
f_Y(y) = (f_X(√y) + f_X(-√y)) / (2√y) (当y>0时)
f_Y(y) = 0 (当y≤0时)
咱们拿标准正态分布的X来举例,用Python实现这个过程:
import numpy as np import matplotlib.pyplot as plt from scipy.stats import norm # 1. 定义X的PDF(这里用标准正态分布) def f_x(x): return norm.pdf(x) # 2. 生成Y的取值范围(避开y=0,避免分母为0) y_values = np.linspace(0.01, 5, 1000) # 3. 代入公式计算Y的PDF值 f_y_values = (f_x(np.sqrt(y_values)) + f_x(-np.sqrt(y_values))) / (2 * np.sqrt(y_values)) # 4. 绘制PDF曲线 plt.figure(figsize=(8, 5)) plt.plot(y_values, f_y_values, label="Y=X²的PDF(解析法)", color="blue") plt.xlabel("Y") plt.ylabel("Probability Density") plt.title("PDF of Y = X² (X ~ Standard Normal)") plt.legend() plt.grid(True) plt.show()
方法2:蒙特卡洛模拟+核密度估计(KDE)
如果变换函数很复杂,推导解析公式太麻烦,蒙特卡洛模拟是更通用的方法——不需要数学推导,靠大量样本近似PDF:
- 生成大量X的随机样本
- 对每个样本计算Y=X²
- 用核密度估计(KDE)拟合样本的分布
代码示例:
import numpy as np import matplotlib.pyplot as plt from scipy.stats import norm, gaussian_kde # 1. 生成10万个X的标准正态样本(样本量越大,近似越准确) np.random.seed(42) # 固定随机种子,保证结果可复现 x_samples = norm.rvs(size=100000) # 2. 计算对应的Y样本 y_samples = x_samples ** 2 # 3. 用KDE估计Y的PDF kde = gaussian_kde(y_samples) y_values = np.linspace(0.01, 5, 1000) f_y_kde = kde(y_values) # 4. 绘制结果(直方图+KDE曲线对比) plt.figure(figsize=(8, 5)) plt.hist(y_samples, bins=50, density=True, alpha=0.3, label="Y的样本直方图") plt.plot(y_values, f_y_kde, label="Y=X²的PDF(KDE)", color="red") plt.xlabel("Y") plt.ylabel("Probability Density") plt.title("PDF of Y = X² (Monte Carlo + KDE)") plt.legend() plt.grid(True) plt.show()
二、多变量变换的情况
至于两个随机变量的函数(比如Z=X+Y、Z=X*Y这类映射),处理思路和单变量一致:要么推导解析公式(需要用到雅可比行列式,适合简单变换),要么用蒙特卡洛+KDE的通用方法,后者更适合复杂场景。
举个例子:假设X和Y都是独立的标准正态分布,计算Z=X+Y的PDF:
import numpy as np import matplotlib.pyplot as plt from scipy.stats import norm, gaussian_kde np.random.seed(42) # 生成X和Y的独立样本 x_samples = norm.rvs(size=100000) y_samples = norm.rvs(size=100000) # 计算Z的样本 z_samples = x_samples + y_samples # 用KDE估计Z的PDF kde_z = gaussian_kde(z_samples) z_values = np.linspace(-5, 5, 1000) f_z_kde = kde_z(z_values) # 绘制结果(同时对比理论PDF:Z~N(0,2)) plt.figure(figsize=(8, 5)) plt.hist(z_samples, bins=50, density=True, alpha=0.3, label="Z的样本直方图") plt.plot(z_values, f_z_kde, label="Z=X+Y的PDF(KDE)", color="red") plt.plot(z_values, norm.pdf(z_values, loc=0, scale=np.sqrt(2)), label="理论PDF(N(0,2))", linestyle="--", color="blue") plt.xlabel("Z") plt.ylabel("Probability Density") plt.title("PDF of Z = X + Y (X,Y ~ Standard Normal)") plt.legend() plt.grid(True) plt.show()
三、推荐的Python工具库
- numpy:用于生成随机样本、数值计算
- scipy.stats:提供各种内置分布的PDF/CDF,以及
gaussian_kde用于核密度估计 - matplotlib:基础绘图库,用于绘制PDF曲线和直方图
- seaborn:基于matplotlib,提供更美观的统计可视化(比如
sns.kdeplot可以直接绘制KDE曲线)
内容的提问来源于stack exchange,提问作者rpavan21
相关产品推荐
相关产品推荐

