使用scipy做lognormal拟合出现两条曲线如何仅保留目标曲线?
问题原因
你的代码存在三处核心错误,导致出现多余的错误曲线、拟合结果不符合预期:
- 生成样本时对数正态分布的偏移参数
loc设为2,但拟合时强制固定floc=0,参数约束和真实数据分布不匹配,拟合结果自然错误 - 你手动绘制的「原始分布」参数完全写错:生成样本用的参数是
shape=0.6, loc=2, scale=1,但你写pdf变量时用了shape=0.5, loc=0, scale=1,这条就是你说的峰值约为0.5的错误曲线 - 直方图的
normed参数在高版本scipy中已经废弃,同时绘图代码重复传入了颜色参数,逻辑冲突
修正方案
如果你只需要保留拟合得到的目标曲线,直接使用以下调整后的代码即可:
import numpy as np import scipy.stats as st import matplotlib.pyplot as plt # 生成模拟样本 samp = st.lognorm(0.6, loc=2, scale=1).rvs(size=2000) # 拟合时不强制固定loc,由算法自动估算参数 param = st.lognorm.fit(samp) print("拟合得到的参数(shape, loc, scale):", param) x = np.linspace(0, 10, 100) # 计算拟合分布的概率密度 pdf_fitted = st.lognorm.pdf(x, param[0], loc=param[1], scale=param[2]) # 仅绘制拟合曲线和样本直方图 plt.plot(x, pdf_fitted, 'r-') plt.hist(samp, bins=30, density=True, alpha=.3) plt.show()
补充说明
如果你需要对比拟合结果和真实生成分布的差异,可以在代码中添加正确的真实分布曲线:
# 正确的真实分布pdf,参数和生成样本时一致 pdf_real = st.lognorm.pdf(x, 0.6, loc=2, scale=1) plt.plot(x, pdf_real, 'g-')
如果你的真实业务数据确定没有偏移(即loc必须为0),那么生成样本时就不要加loc=2参数,拟合时再加floc=0才是合理的约束。
内容的提问来源于stack exchange,提问作者rrkk
相关产品推荐
相关产品推荐

