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

对数正态分布累积重量分数计算代码结果与预期不符,求协助

对数正态分布累积重量分数计算代码排查

我写了一段生成累积重量分数的代码,但计算结果和预期不符(预期结果见附图),麻烦帮忙排查问题。输入参数是D50=1、几何标准差(Geometric Mean Deviation)=0.4,代码如下:

import numpy as np
from scipy.stats import lognorm
import pandas as pd  # 原代码遗漏导入,补充后避免运行报错

def lognormal_cdf(x, D50, gsd):
    # 计算对数正态分布的mu和sigma参数
    sigma = np.sqrt(np.log(1 + (gsd ** 2)))
    mu = np.log(D50) - 0.5 * sigma ** 2
    
    # 计算并返回CDF值
    cdf = lognorm.cdf(x, sigma, scale=np.exp(mu))
    return cdf

D50 = 1.0  # 中位值(D50)
gsd = 0.4   # 几何标准差

# 示例用法
lower_limit = 0.0
upper_limit = 10.0
intervals = 10  # 需要计算CDF的区间数量
diff = (upper_limit - lower_limit) / intervals

lower_limits = np.linspace(lower_limit, upper_limit - diff, intervals)
upper_limits = np.linspace(lower_limit + diff, upper_limit, intervals)

# 计算CDF
cdf_value = lognormal_cdf(upper_limits, D50, gsd)

# 输出结果
df = pd.DataFrame([lower_limits, upper_limits, cdf_value]).T
df.columns = ['lower limits', 'upper limits', 'cumulative mass fraction']
print(df)

当前输出见附图,预期结果见附图。我试过用lognorm.cdf(x, sigma, scale=np.exp(mu))以及网上找的变换方法,问题还是没解决。


问题排查与修正

1. 几何标准差(GSD)的参数转换错误

对数正态分布中,几何标准差GSD和分布参数σ的正确关系是σ = np.log(gsd),你用的sigma = np.sqrt(np.log(1 + (gsd ** 2)))是算术标准差转对数正态σ的公式,完全不适用几何标准差的场景。

2. 位置参数mu的计算错误

D50是对数正态分布的中位数,对数后的中位数就是μ(因为对数正态分布的中位数对应exp(mu)),所以正确计算应为mu = np.log(D50),不需要减去0.5 * sigma ** 2——这个修正仅针对给定算术均值的情况,和D50中位数无关。

修正后的代码

import numpy as np
from scipy.stats import lognorm
import pandas as pd

def lognormal_cdf(x, D50, gsd):
    # 修正后的参数计算逻辑
    sigma = np.log(gsd)
    mu = np.log(D50)
    
    # scipy lognorm参数对应关系:s=sigma,scale=exp(mu)
    cdf = lognorm.cdf(x, s=sigma, scale=np.exp(mu))
    return cdf

D50 = 1.0
gsd = 0.4

lower_limit = 0.0
upper_limit = 10.0
intervals = 10
diff = (upper_limit - lower_limit) / intervals

lower_limits = np.linspace(lower_limit, upper_limit - diff, intervals)
upper_limits = np.linspace(lower_limit + diff, upper_limit, intervals)

cdf_value = lognormal_cdf(upper_limits, D50, gsd)

df = pd.DataFrame([lower_limits, upper_limits, cdf_value]).T
df.columns = ['lower limits', 'upper limits', 'cumulative mass fraction']
print(df)

验证逻辑

对数正态分布CDF的定义是:若变量X~Lognormal(μ,σ),则其CDF为Φ((lnX - μ)/σ)(Φ为标准正态分布CDF)。scipy的lognorm.cdf参数中,s对应σ,scale对应exp(μ),修正后的参数完全匹配这个定义。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:35:28