如何从预定义的正态分布生成对数正态分布并获取对应参数
如何从预定义的正态分布生成对数正态分布并获取对应参数
嘿,这个问题刚好踩中了正态分布和对数正态分布的核心关联,我来一步步帮你捋明白:
首先得明确最关键的关系:如果一个随机变量X服从对数正态分布,那么它的自然对数ln(X)一定服从正态分布。反过来也成立——要是你有一个服从正态分布的变量Z ~ N(μ, σ²),那X = exp(Z)就会妥妥服从对数正态分布。
第一步:把你的正态样本转成对数正态样本
你已经有了生成N(400, 40²)样本的代码,只需要给每个样本点取自然指数,就能得到对应的对数正态样本:
import numpy as np import matplotlib.pyplot as plt import scipy.stats # 原正态分布参数 mu_prev, sigma_prev = 400, 40. # 生成正态分布样本 normal_samples = np.random.normal(mu_prev, sigma_prev, 100000) # 转换为对数正态样本:直接对正态样本取指数 log_normal_samples = np.exp(normal_samples)
第二步:获取对数正态分布的对应参数
对数正态分布有两种常用的参数化方式,看你需求选:
基于对数的正态参数(最直接对应你的输入)
这就是你原来的mu_prev和sigma_prev——因为ln(X) ~ N(mu_prev, sigma_prev²),所以这俩值就是对数正态分布的「潜在正态参数」,像scipy这类工具都会直接用到它们。对数正态自身的均值和方差
如果需要对数正态分布本身的均值和方差,可以用下面的公式计算:- 均值:
exp(mu_prev + sigma_prev² / 2) - 方差:
(exp(sigma_prev²) - 1) * exp(2*mu_prev + sigma_prev²)
代入你的参数试试:
log_norm_mean = np.exp(mu_prev + sigma_prev**2 / 2) log_norm_var = (np.exp(sigma_prev**2) - 1) * np.exp(2*mu_prev + sigma_prev**2) print(f"对数正态均值:{log_norm_mean},对数正态方差:{log_norm_var}")不过要注意,因为你的mu_prev是400,exp(400)是个天文数字,结果会非常夸张,这是正常现象。
- 均值:
第三步:可视化对数正态分布
你原来的可视化代码得调整下,因为对数正态分布的取值范围是(0, +∞),而且数值极大,直接画直方图会挤成一团。建议用对数坐标轴来观察,同时用scipy的lognorm来绘制PDF:
# 绘制对数正态直方图(用对数x轴) count, bins, ignored = plt.hist(log_normal_samples, 1000, density=True) plt.xscale('log') # 用scipy绘制对数正态PDF:s对应sigma_prev,scale对应exp(mu_prev) pdf = scipy.stats.lognorm.pdf(bins, s=sigma_prev, scale=np.exp(mu_prev)) plt.plot(bins, pdf, linewidth=3, color='r') plt.title("Lognormal Distribution (from N(400, 40²))") plt.xlabel("Value (log scale)") plt.ylabel("Density") plt.show()
小提醒
因为原正态均值是400,exp(400)大到离谱,所以生成的对数正态样本会集中在极大的数值区间里,用对数坐标轴能更清晰地看到分布的真实形状。
备注:内容来源于stack exchange,提问作者Landon
相关产品推荐
相关产品推荐

