You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

截断对数正态分布(x<y)的均值计算及正态分布截断均值代码转换需求

计算截断对数正态分布的均值(X < y时)

没问题,我来帮你把正态分布的截断均值代码转换成对数正态分布的版本!首先得理清对数正态和正态分布的核心关系:如果X服从对数正态分布,那么Z = ln(X) 服从正态分布。我们可以利用这个关系,把截断条件转换到正态空间,再通过对数正态的期望公式计算最终结果。

关键原理

对于对数正态变量X,设 ( Z = \ln(X) \sim N(\mu, \sigma^2) )(其中(\sigma)就是你提到的标准差(a),注意这里默认是对数后的标准差;如果是X本身的标准差,需要额外转换,后面会说明)。我们要计算的是 ( E[X \mid X < y] ),等价于计算 ( E[\exp(Z) \mid Z < \ln(y)] ),这个期望可以通过标准正态分布的CDF(累积分布函数)来推导,公式如下:

[
E[X \mid X < y] = \exp\left(\mu + \frac{\sigma^2}{2}\right) \cdot \frac{\Phi\left( \frac{\ln(y) - \mu - \sigma^2}{\sigma} \right)}{\Phi\left( \frac{\ln(y) - \mu}{\sigma} \right)}
]

其中(\Phi(\cdot))是标准正态分布的CDF。

代码实现

下面是对应你给出的正态分布代码的对数正态版本,我们用scipy.stats来实现:

import scipy.stats as stats
import numpy as np

# ************* 替换成你的参数 *************
# ln(X)的均值(如果不知道,可通过X的均值计算:mu = np.log(X_mean) - sigma**2 / 2)
mu = 5.0  
# ln(X)的标准差,对应你说的a
sigma = 1.0  
# 截断上限y
y = 200.0  
# *****************************************

# 转换截断条件到正态空间
c = np.log(y)

# 计算分子和分母
numerator = np.exp(mu + sigma**2 / 2) * stats.norm.cdf( (c - mu - sigma**2) / sigma )
denominator = stats.norm.cdf( (c - mu) / sigma )

# 得到截断对数正态分布的均值
truncated_lognorm_mean = numerator / denominator

print(f"截断对数正态分布的均值(X < {y}):{truncated_lognorm_mean}")

参数说明

  • 如果你只知道X本身的标准差(而非ln(X)的标准差),需要先从X的均值(\mu_X)和标准差(\sigma_X)反推(\mu)和(\sigma):
    [
    \sigma = \sqrt{\ln\left(1 + \left(\frac{\sigma_X}{\mu_X}\right)^2\right)}
    ]
    [
    \mu = \ln(\mu_X) - \frac{\sigma^2}{2}
    ]
    把这两个计算步骤加入代码即可。

和正态截断代码的对应关系

对比你给出的正态截断代码,这里的核心是:

  • 把原截断条件(X < y)转换为(\ln(X) < \ln(y))
  • 利用对数正态的期望公式,结合标准正态CDF完成计算,而不是直接用truncnorm.mean(因为truncnorm是针对正态变量的均值,我们需要的是对数正态变量的条件期望,不是正态变量的)

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

火山引擎 最新活动