Scipy:采样数据点具有相似的值

时间:2018-06-13 16:11:02

标签: python random scipy

我想使用scipy在0.15到10.1范围内从自定义函数中随机抽样。但是,我的样本高度偏向0.15的左边界。实际上,所有50000个采样点都小于0.16。我不确定我的代码有什么问题。

import numpy as np
from scipy import stats

class your_distribution(stats.rv_continuous):
    def _pdf(self, x):
        p0 = 10.9949;
        p1 = 0.394447;
        p2 = 12818.4;
        p3 = 2.38898;
        return ((p1*p3)/(p3*p0+p2*p1))*(p0*np.exp(-1.0*p1*x))+(p2*np.exp(-1.0*p3*x))

distribution = your_distribution(a=0.15, b=10.1)
sample = distribution.rvs(size=50000)

3 个答案:

答案 0 :(得分:1)

您实施为_pdf()的功能不是PDF。要成为PDF,[a,b]上的积分必须为1. PDF的积分不是1,大约是3750:

In [27]: from scipy.integrate import quad

In [28]: quad(distribution.pdf, distribution.a, distribution.b)
Out[28]: (3749.6759222061523, 6.886284755966421e-09)

如果作为快速黑客,我按如下方式修改您的发行版:

class your_distribution(stats.rv_continuous):
    def _pdf(self, x):
        p0 = 10.9949;
        p1 = 0.394447;
        p2 = 12818.4;
        p3 = 2.38898;
        p = ((p1*p3)/(p3*p0+p2*p1))*(p0*np.exp(-1.0*p1*x))+(p2*np.exp(-1.0*p3*x))
        return p / 3749.6759222061523

然后按预期工作。

(这是一个快速的黑客攻击,因为规范化常数通常应取决于ab。)

答案 1 :(得分:0)

您的代码没有问题。问题可能在于您的发行版的定义。随着x变小,这渐渐变大。因此,由于您将分布支持的下限指定为a=0.15,因此该值将对应于渐近概率1

请注意,支持的下限不是x的下限

如果你绘制pdf,你可以检查它是否从x = -292附近的点接收到它的所有质量。通过指定a=0.15生效,您可以将概率峰值移至0.15

我怀疑你想要实现的是x<0.15概率为零的分布。这可以通过修改自定义分布来实现,如下所示

class your_distribution(stats.rv_continuous):
    def _pdf(self, x):
        p0 = 10.9949;
        p1 = 0.394447;
        p2 = 12818.4;
        p3 = 2.38898;
        if x < 0.15:
            return 0
        return ((p1*p3)/(p3*p0+p2*p1))*(p0*np.exp(-1.0*p1*x))+(p2*np.exp(-1.0*p3*x))

答案 2 :(得分:0)

我解决了问题(在朋友的帮助下)!

事实证明我的pdf没有正确规范化,因为我错过了一个括号。正确的pdf是((p1*p3)/(p3*p0+p2*p1))*((p0*np.exp(-1.0*p1*x))+(p2*np.exp(-1.0*p3*x)))