scipy.stats中的分布平均值和标准偏差

2024-03-28 20:55:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图得到对数正态分布的平均值和标准差,其中mu=0.4104857306,sigma=3.4070874277012617,我期望平均值=500,std=600。我不确定我做错了什么。代码如下:

import scipy.stats as stats
import numpy as np
a = 3.4070874277012617
b = 0.4104857306
c = stats.lognorm.mean(a,b)
d = stats.lognorm.var(a,b)
e = np.sqrt(d)
print("Mean =",c)
print("std =",e)

结果如下:

^{pr2}$

提前谢谢你。在

编辑:

谢谢你的帮助。我查了一下,发现有一些计算错误。我现在可以得到平均值=500,但仍然不能得到std=600。以下是我使用的代码:

import numpy as np
import math
from scipy import exp
from scipy.optimize import fsolve

def f(z):
    mean = 500
    std = 600
    sigma = z[0]
    mu = z[1]
    f = np.zeros(2)
    f[0] = exp(mu + (sigma**2) / 2) - mean
    f[1] = exp(2*mu + sigma**2) * exp(sigma**2 - 1) - std**2
    return f
z = fsolve (f,[1.1681794012855686,5.5322865416282365])
print("sigma =",z[0])
print("mu =",z[1])
print(f(z))

sigma = 1.1681794012855686
mu = 5.5322865416282365

我试着用计算器检查结果,我可以根据需要得到std=600,我仍然可以用lognorm.std(sigma, scale=np.exp(mu))得到{}。在


Tags: 代码fromimportnumpyasstatsnpscipy
1条回答
网友
1楼 · 发布于 2024-03-28 20:55:28

为了与其他连续分布一致,^{}对数正态分布以一种稍微不寻常的方式参数化。第一个参数是shape参数,它是您的sigma。后面是locscale参数,它们允许移动和缩放分布。这里需要loc=0.0和{}。所以要计算平均值,你需要做如下操作:

>>> import numpy as np
>>> from scipy.stats import lognorm
>>> mu = 0.4104857306
>>> sigma = 3.4070874277012617
>>> lognorm.mean(sigma, 0.0, np.exp(mu))
500.0000010889041

或者更清楚地说:按名称传递scale参数,并将loc参数保留为其默认值0.0

^{pr2}$

正如@coldspeed在他的评论中所说,你对标准差的期望值看起来不对。我得到:

>>> lognorm.std(sigma, scale=np.exp(mu))
165831.2402402415

我用手工计算得到同样的值。在

为了再次检查这些参数选择是否确实给出了预期的lognormal,我创建了一个一百万个偏差的样本,并查看了该样本的日志的平均值和标准偏差。正如预期的那样,这些返回的值与您原来的mu和{}大致相同:

>>> samples = lognorm.rvs(sigma, scale=np.exp(mu), size=10**6)
>>> np.log(samples).mean()  # should be close to mu
0.4134644116056518
>>> np.log(samples).std(ddof=1)  # should be close to sigma
3.4050012251732285

作为对编辑的回应:您得到的对数正态方差的公式稍微有点错误-您需要将exp(sigma**2 - 1)项替换为(exp(sigma**2) - 1)。如果您这样做,然后重新运行fsolve计算,您将得到:

sigma = 0.9444564779275075
mu = 5.768609079062494

用这些值,你应该得到预期的平均值和标准差:

>>> from scipy.stats import lognorm
>>> import numpy as np
>>> sigma = 0.9444564779275075
>>> mu = 5.768609079062494
>>> lognorm.mean(sigma, scale=np.exp(mu))
499.9999999949592
>>> lognorm.std(sigma, scale=np.exp(mu))
599.9999996859631

与使用fsolve不同,您还可以解析地求解sigma和{},给出所需的平均值和标准差。这样可以更快地获得更准确的结果:

>>> mean = 500.0
>>> var = 600.0**2
>>> sigma = np.sqrt(np.log1p(var/mean**2))
>>> mu = np.log(mean) - 0.5*sigma*sigma
>>> mu, sigma
(5.768609078769636, 0.9444564782482624)
>>> lognorm.mean(sigma, scale=np.exp(mu))
499.99999999999966
>>> lognorm.std(sigma, scale=np.exp(mu))
599.9999999999995

相关问题 更多 >