Python中的对数正态分布

5 投票
1 回答
13734 浏览
提问于 2025-04-27 23:00

我在StackOverflow上看到过几个关于如何拟合对数正态分布的问题。不过我还有两个地方需要澄清一下。

我有一组样本数据,它的对数值是符合正态分布的。所以我可以用scipy.stats.lognorm.fit来拟合这些数据(也就是对数正态分布)。

拟合效果很好,还给了我标准差。下面是我的代码和结果。

import numpy as np
from scipy import stats

sample = np.log10(data) #taking the log10 of the data

scatter,loc,mean = stats.lognorm.fit(sample) #Gives the paramters of the fit 

x_fit = np.linspace(13.0,15.0,100)
pdf_fitted = stats.lognorm.pdf(x_fit,scatter,loc,mean) #Gives the PDF

print "scatter for data is %s" %scatter
print "mean of data is %s" %mean  

这里输入图片描述 结果

scatter for data is 0.186415047243
mean for data is 1.15731050926

从图片中可以明显看到,均值大约是14.2,但我得到的是1.15??!!这是为什么呢?很明显,log(均值)也没有接近14.2!!

这篇文章这个问题中提到,log(均值)才是真正的均值。

但是你可以从我上面的代码看到,我得到的拟合是基于sample = log(data),而且似乎也拟合得很好。不过当我尝试

sample = data
pdf_fitted = stats.lognorm.pdf(x_fit,scatter,loc,np.log10(mean))

拟合似乎就不太成功了。

1) 为什么均值不是14.2?

2) 如何绘制填充/绘制垂直线来显示1个标准差的置信区间?

暂无标签

1 个回答

8

你说

我有一组样本数据,它的对数遵循正态分布。

假设 data 是包含这些样本的数组。要使用 scipy.stats.lognorm 将这些数据拟合到对数正态分布,可以这样做:

s, loc, scale = stats.lognorm.fit(data, floc=0)

现在假设 mu 和 sigma 是基础正态分布的均值和标准差。要从这个拟合中得到这些值的估计,可以使用:

estimated_mu = np.log(scale)
estimated_sigma = s

(这些不是 data 中样本的均值和标准差的估计值。有关对数正态分布的均值和方差的公式,请查看 维基百科页面。)

要将直方图和概率密度函数(PDF)结合在一起,你可以使用,例如:

import matplotlib.pyplot as plt.

plt.hist(data, bins=50, normed=True, color='c', alpha=0.75)
xmin = data.min()
xmax = data.max()
x = np.linspace(xmin, xmax, 100)
pdf = stats.lognorm.pdf(x, s, scale=scale)
plt.plot(x, pdf, 'k')

如果你想查看数据的对数,可以做类似下面的操作。注意这里使用的是正态分布的PDF。

logdata = np.log(data)
plt.hist(logdata, bins=40, normed=True, color='c', alpha=0.75)
xmin = logdata.min()
xmax = logdata.max()
x = np.linspace(xmin, xmax, 100)
pdf = stats.norm.pdf(x, loc=estimated_mu, scale=estimated_sigma)
plt.plot(x, pdf, 'k')

顺便提一下,使用 stats.lognorm 拟合的替代方法是使用 stats.norm.fit 拟合 log(data)

logdata = np.log(data)
estimated_mu, estimated_sigma = stats.norm.fit(logdata)

相关问题:

撰写回答