You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生成对数正态分布随机数为何无法得到预期参数?

对数正态分布随机数生成函数的参数错误修正

问题描述

尝试自行实现生成对数正态分布随机数的函数(用于无现成函数的环境),采用Box-Muller变换生成正态分布随机数后取指数,但生成值的均值和标准差不符合预期,仅分布形状大致正确。原代码如下:

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng()

def f():
    mean = 100
    sigma = 50

    u = np.log((mean * mean) / np.sqrt(mean * mean + sigma * sigma))
    d = np.log(1 + (sigma * sigma) / (mean * mean))

    u1 = 0
    while u1 <= 0.0000001:
        u1 = rng.random()
    u2 = rng.random()

    mag = d * np.sqrt(-2 * np.log(u1))
    z0 = mag * np.cos(2 * np.pi * u2) + u
    z1 = mag * np.sin(2 * np.pi * u2) + u

    return (np.exp(z0), np.exp(z1))

iteration = 100000

data = []
for i in range(0, iteration):
    x = f()
    data.append(x[0])
    data.append(x[1])

fig, ax = plt.subplots()
ax.hist(data, bins=100) 

print('mean: ' + str(np.mean(data)))
print('median: ' + str(np.median(data)))
print('stdev: ' + str(np.std(data)))

问题根源

核心错误出在正态分布标准差的计算上:

  • 对数正态分布的期望μ_X、标准差σ_X,对应取对数后的正态分布的均值μ_Z和标准差σ_Z的转换公式中,σ_Z是sqrt(ln(1 + (σ_X²/μ_X²))),你遗漏了外层的平方根,直接用ln(1 + (σ_X²/μ_X²))作为标准差,导致生成的正态分布离散程度被放大,最终对数正态分布的方差严重偏离预期。

修正后的代码

import matplotlib.pyplot as plt
import numpy as np

rng = np.random.default_rng()

def f():
    mean = 100  # 目标对数正态分布的均值
    sigma = 50  # 目标对数正态分布的标准差

    # 转换为对应正态分布的均值和标准差
    mu_z = np.log((mean ** 2) / np.sqrt(mean ** 2 + sigma ** 2))
    sigma_z = np.sqrt(np.log(1 + (sigma ** 2) / (mean ** 2)))  # 补上缺失的平方根

    u1 = 0
    while u1 <= 1e-7:
        u1 = rng.random()
    u2 = rng.random()

    mag = sigma_z * np.sqrt(-2 * np.log(u1))
    z0 = mag * np.cos(2 * np.pi * u2) + mu_z
    z1 = mag * np.sin(2 * np.pi * u2) + mu_z

    return (np.exp(z0), np.exp(z1))

iteration = 100000

data = []
for i in range(iteration):
    x = f()
    data.append(x[0])
    data.append(x[1])

fig, ax = plt.subplots()
ax.hist(data, bins=100) 

print('mean: ' + str(np.mean(data)))
print('median: ' + str(np.median(data)))
print('stdev: ' + str(np.std(data)))

验证结果

修正后运行代码,生成数据的均值会接近100,标准差接近50:

  • 对数正态分布的中位数理论值为exp(mu_z) = 100²/sqrt(100²+50²) ≈ 89.44,输出的中位数会和这个值一致,符合理论预期。

内容的提问来源于stack exchange,提问作者luiges90

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:04:55