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

Scipy更新后如何获取对数正态分布的众数?

如何在Scipy #21050更新后获取对数正态分布的众数?

Scipy.stats库原本提供了分布的均值、中位数求解函数,但没有直接的众数求解接口,这也是类似Stack Overflow问题的常见场景。在Scipy的#21050更新后,部分连续分布(包括对数正态分布)新增了mode()方法,同时你也可以通过对数正态分布的理论公式直接计算众数,这比数值求解PDF最大值的方式更精准。

方法一:使用Scipy更新后的mode()方法

在Scipy 1.10.0及以后版本中,scipy.stats.lognorm对象新增了mode()方法,调用后可直接返回分布的众数:

import numpy as np
import scipy.stats as stats

# 定义对数正态分布参数(s对应sigma,scale对应exp(mu))
sigma = 1
mu = 0
lognorm_dist = stats.lognorm(sigma, scale=np.exp(mu))

# 直接调用mode()方法获取众数
dist_mode = lognorm_dist.mode()[0]
print(f"Scipy mode()方法获取的众数: {dist_mode}")

方法二:通过理论公式计算

对数正态分布的众数有明确的理论公式:若底层正态分布的均值为mu、标准差为sigma,则对数正态分布的众数为exp(mu - sigma²)。如果是通过fit()方法拟合数据得到的参数,只需提取对应参数代入公式即可:

import numpy as np
import scipy.stats as stats

# 模拟样本数据并拟合对数正态分布参数
data = stats.lognorm.rvs(s=1, scale=np.exp(0), size=1000)
s_fit, loc_fit, scale_fit = stats.lognorm.fit(data)

# 从拟合参数推导mu(scale = exp(mu))
mu_fit = np.log(scale_fit)
sigma_fit = s_fit

# 计算理论众数
theoretical_mode = np.exp(mu_fit - sigma_fit**2)
print(f"理论公式计算的众数: {theoretical_mode}")

原数值求解方案的对比

你提供的数值求解方式是通过寻找PDF最大值对应的x值,这种方法依赖于x的采样密度,精度会受限于采样区间和点数:

import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt

mu, sigma = 0, 1
lognorm_dist = stats.lognorm(sigma, scale=np.exp(mu))

x = np.linspace(0, 10, 1_000)
y = lognorm_dist.pdf(x)
mode = x[np.argmax(y)]

print(f"数值求解的众数: {mode}")
print(f"理论众数: {np.exp(mu - sigma**2)}")

# 可视化对比
plt.plot(x, y, label='对数正态分布PDF')
plt.axvline(mode, color='red', linestyle='--', label=f'数值众数: {mode:.4f}')
plt.axvline(np.exp(mu - sigma**2), color='green', linestyle='--', label=f'理论众数: {np.exp(mu - sigma**2):.4f}')
plt.legend()
plt.show()

三种方式对比下来,mode()方法和理论公式计算的结果一致且精度最高,数值求解的结果会因采样设置略有偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 22:16:06