如何使用scipy.stats.rv_continuous?

16 投票
1 回答
14061 浏览
提问于 2025-04-17 22:37

我一直在寻找一个关于如何使用 rv_continuous 的好教程或示例,但一直没能找到。

我看过:

http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.html#scipy.stats.rv_continuous

但是那并没有太大帮助(而且没有任何使用示例)。

我想做的一个例子是,指定任何概率分布,然后能够调用 fit,接着简单地得到我想要的概率密度函数(pdf),并能够调用 expect 来获取期望值。

到目前为止,我理解的事情是,要创建任何概率分布,我们需要为它创建自己的类,然后继承 rv_continuous。然后通过指定自定义的 _pdf_cdf,我们应该能够简单地使用 rv_continuous 提供的每一个方法。像 expectfit 现在应该都可以用了。

不过,对我来说真正神秘的是,如果我们不明确告诉 rv_continuous 概率分布的参数,它真的能正确执行所有这些方法吗?它怎么仅仅通过 _pdf_cdf 就做到这一点?

还是我只是误解了它的工作原理?

另外,如果你能提供一个简单的示例,说明它是如何工作的,以及如何使用 expect 和/或 fit,那就太好了!或者如果有更好的教程或链接也不错。

提前谢谢你。

1 个回答

15

这里有一个教程:https://docs.scipy.org/doc/scipy/tutorial/stats.html

简单来说,rv_continuous 是用来创建子类的。如果你需要一个在 scipy.stats 中没有定义的分布(总共有70多种),就可以用它。

关于它是怎么工作的。简单来说,它使用了一些通用的代码路径:如果你的子类定义了 _pdf 但没有定义 _logpdf,那么它会继承

def _logpdf(self, x, *args):
    return log(self._pdf(x, *args))

还有一堆类似的方法(具体细节可以查看 https://github.com/scipy/scipy/blob/master/scipy/stats/_distn_infrastructure.py)。

关于参数。你可能是指形状参数,对吧?这些参数会通过检查 _pdf_cdf 的签名自动推断出来,具体可以看 https://github.com/scipy/scipy/blob/master/scipy/stats/_distn_infrastructure.py#L617。如果你想跳过这个检查,可以在实例的构造函数中提供 shapes 参数:

class Mydist(stats.rv_continuous):
    def _pdf(self, x, a, b, c, d):
       return 42
mydist = Mydist(shapes='a, b, c, d')

[严格来说,这只适用于 scipy 0.13 及以上版本。早期版本使用了不同的机制,并且需要 shapes 属性。]

撰写回答