Eri*_*bow 22 python statistics scipy
我一直在尝试使用Scipy获得对数正态分布的结果.我已经拥有Mu和Sigma,所以我不需要做任何其他准备工作.如果我需要更具体(并且我试图利用我对统计数据的有限知识),我会说我正在寻找累积函数(在Scipy下的cdf).问题是我无法弄清楚如何只用0-1的平均值和标准差来做到这一点(即返回的答案应该是0-1的答案).我也不确定dist的哪种方法,我应该用它来得到答案.我已经尝试阅读文档并查看SO,但相关问题(如此和此)似乎没有提供我正在寻找的答案.
这是我正在使用的代码示例.谢谢.
from scipy.stats import lognorm
stddev = 0.859455801705594
mean = 0.418749176686875
total = 37
dist = lognorm.cdf(total,mean,stddev)
Run Code Online (Sandbox Code Playgroud)
更新:
经过一些工作和一些研究后,我得到了更多.但我仍然得到了错误的答案.新代码如下.根据R和Excel,结果应该是.7434,但这显然不是正在发生的事情.我缺少一个逻辑缺陷吗?
dist = lognorm([1.744],loc=2.0785)
dist.cdf(25) # yields=0.96374596, expected=0.7434
Run Code Online (Sandbox Code Playgroud)
更新2: 工作lognorm实现,产生正确的0.7434结果.
def lognorm(self,x,mu=0,sigma=1):
a = (math.log(x) - mu)/math.sqrt(2*sigma**2)
p = 0.5 + 0.5*math.erf(a)
return p
lognorm(25,1.744,2.0785)
> 0.7434
Run Code Online (Sandbox Code Playgroud)
mod*_*tos 29
我知道这有点晚了(差不多一年了!)但我一直在研究scipy.stats中的lognorm函数.很多人似乎对输入参数感到困惑,所以我希望能帮助这些人.上面的例子几乎是正确的,但我发现将平均值设置为位置("loc")参数很奇怪 - 这表示cdf或pdf在值大于均值之前没有"起飞".此外,均值和标准差参数应分别采用exp(Ln(mean))和Ln(StdDev)的形式.
简单地说,参数是(x,shape,loc,scale),参数定义如下:
loc - 没有等价物,这会从您的数据中减去,以便0成为数据范围的下限.
scale - expμ,其中μ是变量对数的平均值.(在拟合时,通常使用数据日志的样本均值.)
shape - 变量日志的标准偏差.
我和大多数拥有此功能的人一样经历了同样的挫折,所以我正在分享我的解决方案.请注意,因为如果没有资源汇编,解释就不是很清楚了.
有关更多信息,我发现这些来源很有用:
这里有一个例子,取自@ serv-inc的答案,在这个页面上发布:
import math
from scipy import stats
# standard deviation of normal distribution
sigma = 0.859455801705594
# mean of normal distribution
mu = 0.418749176686875
# hopefully, total is the value where you need the cdf
total = 37
frozen_lognorm = stats.lognorm(s=sigma, scale=math.exp(mu))
frozen_lognorm.cdf(total) # use whatever function and value you need here
Run Code Online (Sandbox Code Playgroud)
tal*_*ies 15
听起来你想要从已知参数中实例化"冻结"分布.在您的示例中,您可以执行以下操作:
from scipy.stats import lognorm
stddev = 0.859455801705594
mean = 0.418749176686875
dist=lognorm([stddev],loc=mean)
Run Code Online (Sandbox Code Playgroud)
这将为您提供一个lognorm分布对象,其中包含您指定的均值和标准差.然后你可以像这样得到pdf或cdf:
import numpy as np
import pylab as pl
x=np.linspace(0,6,200)
pl.plot(x,dist.pdf(x))
pl.plot(x,dist.cdf(x))
Run Code Online (Sandbox Code Playgroud)

这是你的想法吗?
from math import exp
from scipy import stats
def lognorm_cdf(x, mu, sigma):
shape = sigma
loc = 0
scale = exp(mu)
return stats.lognorm.cdf(x, shape, loc, scale)
x = 25
mu = 2.0785
sigma = 1.744
p = lognorm_cdf(x, mu, sigma) #yields the expected 0.74341
Run Code Online (Sandbox Code Playgroud)
与Excel和R类似,上面的lognorm_cdf函数使用mu和sigma参数化CDF以获得对数正态分布.
虽然SciPy使用shape,loc和scale参数来表征其概率分布,但对于对数正态分布,我发现在变量级别而不是在分布级别上更容易想到这些参数.这就是我的意思......
对数正态变量X与正常变量Z相关如下:
X = exp(mu + sigma * Z) #Equation 1
Run Code Online (Sandbox Code Playgroud)
这与:
X = exp(mu) * exp(Z)**sigma #Equation 2
Run Code Online (Sandbox Code Playgroud)
这可以偷偷地重写如下:
X = exp(mu) * exp(Z-Z0)**sigma #Equation 3
Run Code Online (Sandbox Code Playgroud)
其中Z0 = 0.这个等式的形式如下:
f(x) = a * ( (x-x0) ** b ) #Equation 4
Run Code Online (Sandbox Code Playgroud)
如果您可以在头部可视化方程,则应该清楚公式4中的比例,形状和位置参数分别为:a,b和x0.这意味着在等式3中,尺度,形状和位置参数分别为:exp(mu),sigma和零.
如果你不能非常清楚地想象,那么让我们将等式2重写为一个函数:
f(Z) = exp(mu) * exp(Z)**sigma #(same as Equation 2)
Run Code Online (Sandbox Code Playgroud)
然后看看mu和sigma对f(Z)的影响.下图保持西格玛常数并且变化μ.您应该看到mu垂直缩放f(Z).然而,它以非线性方式这样做; 将μ从0变为1的效果小于将mu从1变为2 的效果.从等式2可以看出,exp(mu)实际上是线性比例因子.因此,SciPy的"比例"是exp(mu).
下一个数字保持mu不变并且变化sigma.您应该看到f(Z)的形状发生变化.也就是说,当Z = 0 时,f(Z)具有恒定值,并且sigma影响f(Z)远离水平轴弯曲的速度.因此,SciPy的"形状"就是西格玛.