0

如果有人可以帮助我了解我哪里出错了,我将不胜感激。我有一些描述概率分布的数据。数据为我提供了 P10、P50 和 P90 的值。我也知道分布是对数正态分布。

我已经读过,对于一个对数正态分布的随机变量 X,然后 Y = ln(X) 具有正态分布 - 例如维基百科(https://en.wikipedia.org/wiki/Log-normal_distribution)。

但是,当我尝试使用 scipystats 和 numpy 来理解这一点时,我无法让它成为现实。因为我知道这是真的,而且我知道我在这些 python 库中使用的简单函数没有问题,所以我知道我在某处的理解存在差距。我只是,为了我的一生,看不到我错过了什么......

我正在使用的代码是:

    # build a lognormal distribution with scipystats (ss):

    # set parameters (based on the standard normal distribution mu=0 and sigma=1:
    s, mu, sd, size = 0.5,0,1,100000

    # save the distribution:
    X = ss.lognorm.rvs(s,loc=mu,scale=sd,size=size)

    # convert to normal distribution (i.e. calc the natural log of X):
    Y = np.log(X)

    # Check if Y is normal using ratio between p90-p50 and p50-p10 - should be 1:
    p10,p50,p90 = np.percentile(Y,[10,50,90])
    (p90-p50)/(p50-p10)

以上返回 0.9932 - 或其他非常接近 1 的值。到目前为止一切都很好。我可以随心所欲地改变 s 和缩放(或到目前为止已经尝试过),并且正常测试总是接近 1。如果我改变均值(mu,loc),问题就来了:

    # build a lognormal distribution with scipystats (ss):

    # set parameters (normal distribution mu=100 and sigma=10:
    s, mu, sd, size = 0.5,100,10,100000

    # save the distribution:
    X = ss.lognorm.rvs(s,loc=mu,scale=sd,size=size)

    # convert to normal distribution (i.e. calc the natural log of X):
    Y = np.log(X)

    # Check if Y is normal using ratio between p90-p50 and p50-p10 - should be 1:
    p10,p50,p90 = np.percentile(Y,[10,50,90])
    (p90-p50)/(p50-p10)

在这种情况下,我得到的答案是 1.8 左右——即不是正态分布。就像我说的那样,我显然误解了某些东西,但我看不出它是什么。

综上所述,如果我用ss.lognorm.rvsloc 不为 0 来计算一系列对数正态分布的随机变量,然后用它np.log来得到随机变量的自然对数,那么这个新的分布不是正态分布的,表面上看,似乎违反了该问题顶部链接的维基百科文章顶部描述的规则!

我非常感谢任何人可以给我的任何帮助 - 我只是想确信我了解如何将对数正态数据与正态曲线联系起来!

4

1 回答 1

0

查看这些方法来检查 scipy.stats 中的工作方式:

In [95]: ss.lognorm(s=0.1).mean()                                                                                                                                                                                  
Out[95]: 1.005012520859401

In [96]: np.exp(0.1**2 / 2)                                                                                                                                                                                        
Out[96]: 1.005012520859401

In [97]: ss.lognorm(s=0.1).var()                                                                                                                                                                                   
Out[97]: 0.010151172942587642

In [98]: (np.exp(0.1**2) - 1) * np.exp(0.1 **2)                                                                                                                                                                    
Out[98]: 0.010151172942587642

我发现 scipy.stats 约定有点令人困惑,每次都必须经过。

于 2020-05-04T12:40:18.653 回答