在R与SciPy中拟合对数正态分布


10

我已经使用R与一组数据拟合了对数正态模型。结果参数为:

meanlog = 4.2991610 
sdlog = 0.5511349

我想将此模型转移到Scipy,这是我以前从未使用过的模型。使用Scipy,我可以得到1和3.1626716539637488488 + 90的形状和比例-非常不同的数字。我也尝试过使用meanlog和sdlog的exp,但是继续得到奇怪的图形。

我已经阅读了所有关于scipy的文档,但是对于这种情况下的形状和比例参数仍然感到困惑。自己编写该函数是否有意义?不过,这似乎容易出错,因为我是scipy的新手。

SCIPY对数正态(BLUE)与R对数正态(RED): Scipy对数正态(BLUE)与R对数正态(RED)

对采取什么方向有任何想法吗?顺便说一下,这些数据非常适合R模型,因此,如果看起来像Python中的其他内容,请随时共享。

谢谢!

更新:

我正在运行Scipy 0.11

这是数据的子集。实际样本为38k +,平均值为81.53627:

子集:

x
[60,170,137,138,81,140,78,46,1,168,138,148,145,35,82,126,66,147,88,106,80,54,83,13,
102、54、134、34 ] numpy.mean(x)
99.071428571428569

或者:

我正在研究捕获pdf的功能:

def lognoral(x, mu, sigma):
    a = 1 / (x * sigma * numpy.sqrt(2 * numpy.pi) )
    b = - (numpy.log(x) - mu) ^ 2 / (2 * sigma ^ 2)
    p = a * numpy.exp(b)
    return p

但是,这给了我以下数字(我尝试了几种,以防我混淆了sdlog和meanlog的含义):

>>> lognormal(54,4.2991610, 0.5511349)
0.6994656085799437
 >>> lognormal(54,numpy.exp(4.2991610), 0.5511349)
0.9846125119455129
>>> lognormal(54,numpy.exp(4.2991610), numpy.exp(0.5511349))
0.9302407837304372

有什么想法吗?

更新:

用“ UPQuark”的建议重新运行:

形状,位置,比例(1.0,50.03445923295007,19.074457156766517)

该图的形状非常相似,但峰值出​​现在21附近。


这个问题和答案可以帮助:stackoverflow.com/questions/8747761/...
jbowman

谢谢,我发现了这一点,并学会了与对数正态的“拟合”。但是,我的问题是为什么我会得到如此不同的分布?
莉莲·米拉格罗斯·卡拉斯奎洛

您正在使用SciPy 0.9吗?另外,您可以发布您的数据或其一部分吗?
jbowman 2012年

更新!顺便说一句,它是Scipy 0.11。因此,我读过的错误不应该相关;)
Lillian Milagros Carrasquillo 2012年

Answers:


11

我在源代码中竭尽全力,对scipy lognormal例程进行了以下解释。

xlocscaleLognormal(σ)

其中是“形状”参数。 σ

scipy参数和R参数之间的等价如下:

loc-无等效项,将从您的数据中减去该值,以便0成为数据范围的最小值。

标度-,其中是变量对数的均值。(拟合时,通常将使用数据日志的样本均值。) μexpμμ

shape-变量对数的标准偏差。

我分别调用lognorm.pdf(x, 0.55, 0, numpy.exp(4.29))了参数在哪里(x,shape,loc,scale),并生成了以下值:

x pdf

10 0.000106

20 0.002275

30 0.006552

40 0.009979

50 0.114557

60 0.113479

70 0.103327

80 0.008941

90 0.007494

100 0.006155

这似乎与您的R曲线非常吻合。


谢谢@JBowman,这正是我需要的解释,输出也正是我的发行版。
莉莲·米拉格罗斯·卡拉斯奎洛

8

SciPy中的对数正态分布符合SciPy中所有分布的一般框架。它们都有一个scale和location关键字(如果未明确提供,则默认为0和1)。这使得所有分布都可以从其规范化规范中转移和缩放,这对分布的统计信息具有明显的含义。分布通常也具有一个或多个“形状”参数(尽管有些分布(如正态分布)不需要任何其他参数)。

尽管这种通用方法很好地统一了所有分布,但对于对数正态,由于其他软件包定义参数的方式,它可能会造成一些混乱。但是,如果您是指log(基础分布的平均值)和sdlog(基础分布的标准偏差),则匹配任何对数正态分布都非常简单。

首先,确保将location参数设置为0。然后,将shape参数设置为sdlog的值。最后,将scale参数设置为math.exp(meanlog)。因此,rv = scipy.stats.lognorm(0.5511349,scale = math.exp(4.2991610))将创建一个分布对象,其pdf与R生成的曲线完全匹配。由于x = numpy.linspace(0,180,1000); plot(x,rv.pdf(x))将进行验证。

基本上,SciPy对数正态分布是标准对数正态分布的概括,当将location参数设置为0时,它与标准正好匹配。

使用.fit方法拟合数据时,还可以使用关键字f0..fn,floc和fshape来固定任何形状,位置和/或比例参数,并且仅适合其他变量。对于对数正态分布,这非常有用,因为通常您知道location参数应该固定为0。因此,scipy.stats.lognorm.fit(dataset,floc = 0)始终将location参数返回为0,而仅改变另一个形状和比例参数。


3

Scipy对数正态拟合将返回形状,位置和比例。我只是对一组样本价格数据执行了以下操作:

shape, loc, scale = st.lognorm.fit(d_in["price"])

这给了我合理的估计值1.0、0.09、0.86,并且在绘制它时,应该考虑所有三个参数。

形状参数是基础正态分布的标准偏差,小数位是正态平均值的指数。

希望这可以帮助。


多谢您的回覆!一旦有了这些值(位置,比例,形状),我就会尝试为我关心的每个x查找pdf(x)(这里的值从0到180,不包括在内)。scipy.stats.lognorm.pdf(i,loc,scale,shape)但是,绘制这些图形可以得到上面的图形。
莉莲·米拉格罗斯·卡拉斯奎洛

好的,我看到您只提到形状和比例,这就是为什么我提到从fit()默认返回三个参数的原因。您还说过,您对形状和比例参数的含义感到困惑,我试图解决这个问题。但是,我从来没有像您这样的情况使用对数正态拟合返回荒谬的值,location参数是什么?
upquark 2012年

刚刚更新了问题以回答该问题。感谢您对此的思考。
Lillian Milagros Carrasquillo 2012年

调用scipy.stats.lognorm.pdf(x,shape,loc,scale)而不是scipy.stats.lognorm.pdf(i,loc,scale,shape)。
upquark 2012年

谢谢,upquark,我也做了类似的结果。图的整体形状仍然与R中给出的预期结果大不相同。实际上,它看起来与R中的分布完全不同。
莉莲·米拉格罗斯·卡拉斯奎洛

1

似乎Scipy中对数正态的分布与R中的分布不同,或者通常与我熟悉的分布不相同。约翰·库克(John D Cook)谈到了这一点:http : //www.johndcook.com/blog/2010/02/03/statistical-distributions-in-scipy/ http://www.johndcook.com/distributions_scipy.html

但是,关于如何在Python中使用对数正态密度函数,我尚未找到任何结论。如果有人想添加到此,请随时。

到目前为止,我的解决方案是使用对数正态pdf评估为0到180(不包括),并在python脚本中用作字典。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.