在Python中定义自定义概率密度函数


20

有没有一种方法,可以使用一些已建立的Python程序包(例如SciPy)来定义我自己的概率密度函数(没有任何先验数据,只需),然后我就可以用它进行计算(例如获得连续随机变量的方差)?当然,我可以使用SymPy或Sage创建一个符号函数并执行操作,但是我想知道是否可以代替使用我自己已经完成的软件包而不是自己完成所有这些工作。f(x)=ax+b


感谢您的简单方法!您如何生成随机数直方图,以实现定义自定义分布函数的这种方式?
阿格罗瓦尔(Akur Agrawal)

Answers:


23

您必须在scipy.stats中将rv_continuous类子类化

import scipy.stats as st

class my_pdf(st.rv_continuous):
    def _pdf(self,x):
        return 3*x**2  # Normalized over its range, in this case [0,1]

my_cv = my_pdf(a=0, b=1, name='my_pdf')

现在my_cv是具有给定PDF和范围[0,1]的连续随机变量

请注意,在这个例子中my_pdfmy_cv是任意的名字(这可能是任何东西),但_pdf就是不能随心所欲; 和_cdfst.rv_continuous其中的一种方法,必须重写其中的一种方法才能使子类起作用。


@GertVdE:def _pdf中的“ self”有什么作用?
Srivatsan 2014年


这里的归一化存在问题:您需要给出归一化的概率分布函数(3*x**2,此处),否则所得的随机变量会产生不正确的结果(my_cv.median()例如,您可以检查)。我修复了代码。
Eric O Lebigot

@EOL我发现您对术语“规范化”的使用令人困惑。我认为,需要将函数定在0的中心并将其缩放为1。但是,这个答案似乎暗示着规范化必须在x[0,1] 的范围内。你能澄清一下吗?
dbliss

1
也许标准方法是使用my_cv.rvs()(可以接受一个size参数,一次获得多个样本)。这就是我从文档(docs.scipy.org/doc/scipy/reference/generated/…)中得出的结论
Eric O Lebigot

15

您应该查看sympy.stats。它提供了一个接口来处理随机变量。以下示例提供了X在单位间隔上定义的具有密度的随机变量2x

In [1]: from sympy.stats import *
In [2]: x = Symbol('x')
In [3]: X = ContinuousRV(x, 2*x, Interval(0, 1))

In [4]: P(X>.5) 
Out[4]: 0.750000000000000

In [5]: Var(X) # variance
Out[5]: 1/18

In [6]: E(2*cos(X)+X**2) # complex expressions are ok too
Out[6]: -7/2 + 4cos(1) + 4sin(1)

如果您有兴趣,此抽象可以处理一些相当复杂的操作。


哇...太棒了!非常感谢您的贡献。我会继续这样的眼睛和你的博客
astrojuanlu
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.