拟合和绘制对数正态分布
Fitting and Plotting Lognormal
我在做一些相对简单的事情时遇到了麻烦:
- 从具有一定均值和方差的高斯分布中抽取 N 个样本
- 记录那 N 个样本
- 拟合对数正态分布(使用 stats.lognorm.fit)
- 吐出一个没有 inf 值的漂亮而平滑的对数正态 pdf(使用 stats.lognorm.pdf)
这是我得到的输出的一个小示例:
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import math
%matplotlib inline
def lognormDrive(mu,variance):
size = 1000
sigma = math.sqrt(variance)
np.random.seed(1)
gaussianData = stats.norm.rvs(loc=mu, scale=sigma, size=size)
logData = np.exp(gaussianData)
shape, loc, scale = stats.lognorm.fit(logData, floc=mu)
return stats.lognorm.pdf(logData, shape, loc, scale)
plt.plot(lognormDrive(37,0.8))
正如您可能注意到的那样,情节完全没有意义。
有什么想法吗?
我关注了这些帖子:POST1 POST2
提前致谢!
详细说明:我正在构建一个小脚本,它将
- 获取原始数据并拟合核分布(经验分布)
- 根据数据的均值和方差假设不同的分布。这将是高斯分布和对数正态分布
- 使用 interact
将这些分布与经验分布一起绘制
- 当转动均值和方差的旋钮(并最终偏斜)时,计算不同分布之间的 Kullbeck-Leibler 散度
在对 lognorm.fit()
的调用中,使用 floc=0
,而不是 floc=mu
。
(lognorm
分布的 location 参数简单地翻译了分布。你几乎不想用对数正态分布来做到这一点。)
见A lognormal distribution in python
顺便说一句,您绘制的是未排序样本值的 PDF,因此更正后的脚本中的绘图看起来不会有太大不同。您可能会发现根据排序后的值绘制 PDF 更有用。这是对您的脚本的修改,它使用排序的样本创建 PDF 图:
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import math
def lognormDrive(mu,variance):
size = 1000
sigma = math.sqrt(variance)
np.random.seed(1)
gaussianData = stats.norm.rvs(loc=mu, scale=sigma, size=size)
logData = np.exp(gaussianData)
shape, loc, scale = stats.lognorm.fit(logData, floc=0)
print "Estimated mu:", np.log(scale)
print "Estimated var: ", shape**2
logData.sort()
return logData, stats.lognorm.pdf(logData, shape, loc, scale)
x, y = lognormDrive(37, 0.8)
plt.plot(x, y)
plt.grid()
plt.show()
脚本打印:
Estimated mu: 37.0347152587
Estimated var: 0.769897988163
并创建以下图:
我在做一些相对简单的事情时遇到了麻烦:
- 从具有一定均值和方差的高斯分布中抽取 N 个样本
- 记录那 N 个样本
- 拟合对数正态分布(使用 stats.lognorm.fit)
- 吐出一个没有 inf 值的漂亮而平滑的对数正态 pdf(使用 stats.lognorm.pdf)
这是我得到的输出的一个小示例:
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import math
%matplotlib inline
def lognormDrive(mu,variance):
size = 1000
sigma = math.sqrt(variance)
np.random.seed(1)
gaussianData = stats.norm.rvs(loc=mu, scale=sigma, size=size)
logData = np.exp(gaussianData)
shape, loc, scale = stats.lognorm.fit(logData, floc=mu)
return stats.lognorm.pdf(logData, shape, loc, scale)
plt.plot(lognormDrive(37,0.8))
正如您可能注意到的那样,情节完全没有意义。
有什么想法吗?
我关注了这些帖子:POST1 POST2
提前致谢!
详细说明:我正在构建一个小脚本,它将
- 获取原始数据并拟合核分布(经验分布)
- 根据数据的均值和方差假设不同的分布。这将是高斯分布和对数正态分布
- 使用 interact 将这些分布与经验分布一起绘制
- 当转动均值和方差的旋钮(并最终偏斜)时,计算不同分布之间的 Kullbeck-Leibler 散度
在对 lognorm.fit()
的调用中,使用 floc=0
,而不是 floc=mu
。
(lognorm
分布的 location 参数简单地翻译了分布。你几乎不想用对数正态分布来做到这一点。)
见A lognormal distribution in python
顺便说一句,您绘制的是未排序样本值的 PDF,因此更正后的脚本中的绘图看起来不会有太大不同。您可能会发现根据排序后的值绘制 PDF 更有用。这是对您的脚本的修改,它使用排序的样本创建 PDF 图:
from scipy import stats
import numpy as np
import matplotlib.pyplot as plt
import math
def lognormDrive(mu,variance):
size = 1000
sigma = math.sqrt(variance)
np.random.seed(1)
gaussianData = stats.norm.rvs(loc=mu, scale=sigma, size=size)
logData = np.exp(gaussianData)
shape, loc, scale = stats.lognorm.fit(logData, floc=0)
print "Estimated mu:", np.log(scale)
print "Estimated var: ", shape**2
logData.sort()
return logData, stats.lognorm.pdf(logData, shape, loc, scale)
x, y = lognormDrive(37, 0.8)
plt.plot(x, y)
plt.grid()
plt.show()
脚本打印:
Estimated mu: 37.0347152587
Estimated var: 0.769897988163
并创建以下图: