Python中的对数正态分布

5
我在stackoverflow上看到了几个关于如何拟合对数正态分布的问题。但是我需要知道两个澄清问题。
我有一组样本数据,其对数遵循正态分布。因此,我可以使用scipy.stats.lognorm.fit(即log-normal分布)来拟合数据。
拟合效果良好,并且还给出了标准差。以下是我的代码和结果。
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?!为什么会这样?显然,对数(平均值)也不接近14.2!
此帖子此问题中提到,对数(平均值)是实际平均值。
但是从我的代码中可以看出,我得到的拟合结果使用了sample = log(data),并且似乎也很好地拟合了。然而,当我尝试...
sample = data
pdf_fitted = stats.lognorm.pdf(x_fit,scatter,loc,np.log10(mean))

这个适配似乎不起作用。

1) 为什么平均值不是14.2?

2) 如何绘制填充/绘制垂直线以显示1 sigma置信区间?


请张贴数据子集或伪造数据,以复制问题,以便我们可以测试您的示例代码。 - BKay
http://www.filehosting.org/file/details/460413/test.txt 这是一个包含数据的文本文件。 - Srivatsan
1
你展示的平均值是log(mean),10.**1.15731=14.36。 - CT Zhu
@CTZhu 谢谢你的信息!但是我尝试了另一个样本,其平均值为14.1,但我得到了1.07,对于10**1.0711.24 - Srivatsan
你可能会在stats.stackexchange.com上获得更多的关注。那里有更多的人可以回答这样的问题。 - Robert Dodier
显示剩余2条评论
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样本的平均数和标准差估计值。有关以mu和sigma为参数的对数正态分布的均值和方差公式,请参见维基百科页面
要结合直方图和概率密度函数,您可以使用以下方法之一:
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)

相关问题:


1
现在这是一种非常巧妙的方法!我从来没有想过使用 norm.fit 和使用 log(data),它完美地工作了! - Srivatsan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接