gpt4 book ai didi

python - 使用观测数据的形状生成随机对数正态分布

转载 作者:太空狗 更新时间:2023-10-30 01:17:00 24 4
gpt4 key购买 nike

我正在尝试使一些数据符合对数正态分布,并使用优化参数从中生成随机对数正态分布。经过一番搜索,我找到了一些解决方案,但没有一个令人信服:

solution1 使用拟合函数:

import  numpy as np
from scipy.stats import lognorm

mydata = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354]

shape, loc, scale = lognorm.fit(mydata)
rnd_log = lognorm.rvs (shape, loc=loc, scale=scale, size=100)

或使用原始数据的 mu 和 sigma 的解决方案 2:

import  numpy as np
from scipy.stats import lognorm

mydata = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354]

mu = np.mean([np.log(i) for i in mydata])
sigma = np.std([np.log(i) for i in mydata])

distr = lognorm(mu, sigma)
rnd_log = distr.rvs (size=100)

这些解决方案都不合适:

import pylab
pylab.plot(sorted(mydata, reverse=True), 'ro')
pylab.plot(sorted(rnd_log, reverse=True), 'bx')

我不确定我是否很好地理解了使用发行版的方式,或者我是否遗漏了其他东西......

虽然我在这里找到了解决方案:Does anyone have example code of using scipy.stats.distributions?但是我无法从我的数据中获取形状...我在使用拟合函数时是否遗漏了什么?

谢谢

编辑:

这是一个示例,以便更好地理解我的问题:

print 'solution 1:'
means = []
stdes = []
distr = lognorm(mu, sigma)
for _ in xrange(1000):
rnd_log = distr.rvs (size=100)
means.append (np.mean([np.log(i) for i in rnd_log]))
stdes.append (np.std ([np.log(i) for i in rnd_log]))
print 'observed mean:',mu , 'mean simulated mean:', np.mean (means)
print 'observed std :',sigma, 'mean simulated std :', np.mean (stdes)

print '\nsolution 2:'
means = []
stdes = []
shape, loc, scale = lognorm.fit(mydata)
for _ in xrange(1000):
rnd_log = lognorm.rvs (shape, loc=loc, scale=scale, size=100)
means.append (np.mean([np.log(i) for i in rnd_log]))
stdes.append (np.std ([np.log(i) for i in rnd_log]))
print 'observed mean:',mu , 'mean simulated mean:', np.mean (means)
print 'observed std :',sigma, 'mean simulated std :', np.mean (stdes)

结果是:

solution 1:
observed mean: 1.82562655734 mean simulated mean: 1.18929982267
observed std : 1.39003773799 mean simulated std : 0.88985924363

solution 2:
observed mean: 1.82562655734 mean simulated mean: 4.50608084668
observed std : 1.39003773799 mean simulated std : 5.44206119499

而如果我在 R 中做同样的事情:

mydata <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354)
meanlog <- mean(log(mydata))
sdlog <- sd(log(mydata))
means <- c()
stdes <- c()
for (i in 1:1000){
rnd.log <- rlnorm(length(mydata), meanlog, sdlog)
means <- c(means, mean(log(rnd.log)))
stdes <- c(stdes, sd(log(rnd.log)))
}

print (paste('observed mean:',meanlog,'mean simulated mean:',mean(means),sep=' '))
print (paste('observed std :',sdlog ,'mean simulated std :',mean(stdes),sep=' '))

我得到:

[1] "observed mean: 1.82562655733507 mean simulated mean: 1.82307191072317"
[1] "observed std : 1.39704049131865 mean simulated std : 1.39736545866904"

那更接近了,所以我想我在使用 scipy 时做错了什么......

最佳答案

scipy 中的对数正态分布参数化与通常的方式略有不同。查看scipy.stats.lognorm文档,尤其是“注释”部分。

以下是获得预期结果的方法(请注意,我们在拟合时将位置保持为 0):

In [315]: from scipy import stats

In [316]: x = np.array([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,8,8,8,8,8,9,9,9,10,10,11,12,13,14,14,15,19,19,21,23,25,27,28,30,31,36,41,45,48,52,55,60,68,75,86,118,159,207,354])

In [317]: mu, sigma = stats.norm.fit(np.log(x))

In [318]: mu, sigma
Out[318]: (1.8256265573350701, 1.3900377379913127)

In [319]: shape, loc, scale = stats.lognorm.fit(x, floc=0)

In [320]: np.log(scale), shape
Out[320]: (1.8256267737298788, 1.3900309739954713)

现在您可以生成样本并确认您的期望:

In [321]: dist = stats.lognorm(shape, loc, scale)

In [322]: means, sds = [], []

In [323]: for i in xrange(1000):
.....: sample = dist.rvs(size=100)
.....: logsample = np.log(sample)
.....: means.append(logsample.mean())
.....: sds.append(logsample.std())
.....:

In [324]: np.mean(means), np.mean(sds)
Out[324]: (1.8231068508345041, 1.3816361818739145)

关于python - 使用观测数据的形状生成随机对数正态分布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8703954/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com