在创建截尾连续分布时使用scipy的rv_continuous方法

dkqlctbz  于 2023-04-21  发布在  其他
关注(0)|答案(3)|浏览(149)

我试图计算E[f(x)]的一些pdf,我生成/估计的数据。
它在文档中说:
子类化
新的随机变量可以通过子类化rv_continuous类并重新定义至少_pdf或_cdf方法(标准化为位置0和尺度1)来定义,该方法将被赋予干净的参数(在a和b之间)并通过参数检查方法。
如果肯定参数检查对于RV不正确,则还需要重新定义_argcheck方法。
所以我子类化并定义了_pdf,但每当我尝试调用:
print my_continuous_rv.expect(lambda x: x)
Scipy对我喊道:

AttributeError: 'your_continuous_rv' object has no attribute 'a'

这是有意义的,因为我猜它试图找出积分的下限,因为它也打印在错误中:

lb = loc + self.a * scale

我尝试将属性self.a和self.b定义为(我认为这是定义rv的限制/区间):

self.a = float("-inf")
self.b = float("inf")

然而,当我这样做时,它会抱怨并说:

if N > self.numargs:
AttributeError: 'your_continuous_rv' object has no attribute 'numargs'

我不是很确定numargs应该是什么,但在github上检查scipy的代码后,看起来有这行代码:

if not hasattr(self, 'numargs'):
    # allows more general subclassing with *args
    self.numargs = len(shapes)

我假设这是随机变量的形状,我的函数应该采取。
目前我只做了一个非常简单的随机变量,一个浮点数作为它的可能值。所以我决定硬编码numargs为1。但这只会导致scipy的更多叫喊。
因此,归结起来,我认为从文档中我不清楚当我子类化它时我必须做什么,因为我做了他们所说的,覆盖_pdf,但在这样做之后,它要求我self.a,我硬编码,然后它要求我numargs,在这一点上,我想我得出结论,我真的不知道他们希望我如何子类化,rv_continuous.有人知道吗?我可以从我想要拟合的数据中生成我想要的pdf,然后就可以从pdf中获得期望值和类似的东西,我还需要在rv_continuous中初始化什么,以便它实际工作?

fjnneemd

fjnneemd1#

由于历史原因,scipy发行版是 instances,因此您需要拥有子类的示例。例如:

>>> class MyRV(stats.rv_continuous):
...    def _pdf(self, x, k):
...      return k * np.exp(-k*x)
>>> my_rv = MyRV(name='exp', a=0.)     # instantiation

请注意,需要指定支撑的限制:默认值为a=-infb=inf

>>> my_rv.a, my_rv.b
(0.0, inf)
>>> my_rv.numargs        # gets figured out automagically
1

一旦你指定了_pdf,你就有了一个工作的分发示例:

>>> my_rv.cdf(4, k=3)
0.99999385578764677
>>> my_rv.rvs(k=3, size=4)
array([ 0.37696127,  1.10192779,  0.02632473,  0.25516446])
>>> my_rv.expect(lambda x: 1, args=(2,))    # k=2 here
0.9999999999999999
deyfvvtc

deyfvvtc2#

SciPy的rv_histogram方法允许您提供数据,它提供了pdf,cdf和随机生成方法。

dsekswqp

dsekswqp3#

我的猜测是,您指定了一个带有__init__的构造函数,但没有调用rv_continuous的基类构造函数。
如果从文档中获取示例并添加一个构造函数,如下所示

from scipy.stats import rv_continuous
class gaussian_gen(rv_continuous):
    "Gaussian distribution"
    def __init__(self, **kwargs):
        pass
        #rv_continuous.__init__(self, **kwargs)
    def _pdf(self, x):
        return np.exp(-x**2 / 2.) / np.sqrt(2.0 * np.pi)

gaussian = gaussian_gen(name='gaussian')
print(gaussian.pdf(3))

pdf的调用将失败。如果注解掉对rv_continous.__init__的调用,它将工作,因为基类构造函数将向示例添加所有必要的字段。

相关问题