【问题标题】:Creating sample from custom distribution using scipy使用 scipy 从自定义分发创建示例
【发布时间】:2023-03-30 17:02:01
【问题描述】:

我试图从给定分布中获取一些样本,实际上,它是一个 3 参数帕累托分布。以下是代码:

from scipy.stats import gamma, rv_continuous

class pareto3_pdf(rv_continuous):
    def _pdf(self,x,alpha,lambd,k):
        return (gamma(alpha + k) * lambd**alpha * x**(k - 1)) / (gamma(alpha) * gamma(k) * (lambd + x)**(alpha + k))
pareto3 = pareto3_pdf(name="pareto")


x = pareto3.rvs(alpha = 3,lambd = 4,k = 2)
print(x)

和输出:TypeError: unsupported operand type(s) for *: 'rv_frozen' and 'int'

我不太确定如何解决这个问题。如果有人有任何建议,将不胜感激。

提前谢谢你。

编辑:

我现在更改了代码,但它总是给出负值。

import scipy.stats as stats
from scipy.stats import rv_continuous
from scipy.special import gamma

class pareto3_pdf(rv_continuous):
    def _pdf(self,x,alpha,lambd,k):
        return (gamma(alpha + k) * lambd**alpha * x**(k - 1)) / (gamma(alpha) * gamma(k) * (lambd + x)**(alpha + k))
pareto3 = pareto3_pdf(name="pareto")
pare3 = pareto3.rvs(alpha = 5,lambd = 4,k = 2)
print(pare3)

如果我尝试将其简化为 2 参数模型,OverflowError: (34, 'Result too large') 错误弹出窗口。

import scipy.stats as stats
from scipy.stats import rv_continuous
from scipy.special import gamma

class pareto2_pdf(rv_continuous):
    def _pdf(self,x,alpha,lambd):
        return (alpha * lambd**alpha / (lambd + x)**(alpha + 1))
pareto2 = pareto2_pdf(name="pareto2")
pare2 = pareto2.rvs(alpha = 2,lambd = 2)
print(pare2)

【问题讨论】:

    标签: python scipy distribution


    【解决方案1】:

    您必须从 scipy.special 而不是 scipy.stats 导入 gamma。
    原因是scipy.stats.gamma是分布,scipy.special.gamma是伽玛函数。

    from scipy.stats import rv_continuous 
    from scipy.special import gamma 
    
    class pareto3_pdf(rv_continuous):
        def _pdf(self,x,alpha,lambd,k):
            return (gamma(alpha + k) * lambd**alpha * x**(k - 1)) /(gamma(alpha) * gamma(k) * (lambd + x)**(alpha + k))
    pareto3 = pareto3_pdf(name="pareto")
    x = pareto3.rvs(alpha = 3,lambd = 4,k = 2)
    

    【讨论】:

    • 谢谢!但它一直给我负数,有什么建议吗?
    • 我猜你必须在你的类中添加 _argcheck 方法。但我不知道如何正确地做到这一点
    【解决方案2】:

    正如我所写的elsewhere,您的发行版在 SciPy 中以betaprime(k, alpha, scale=lamda) 的形式提供,因此对其进行采样是内置的。一个小测试:

    from scipy.stats import betaprime
    alpha, lamda, k = 5, 4, 2
    sample = betaprime.rvs(k, alpha, scale=lamda, size=1000)
    print(sample.mean())
    print(betaprime.mean(k, alpha, scale=lamda))
    

    打印

    2.0134570579012108
    2.0
    

    足够接近。 (当然,随机样本的均值是随机的。)

    【讨论】:

    • 谢谢,我发现这两个参数版本其实是Lomax发行版,谢谢大家的帮助。
    猜你喜欢
    • 2014-05-16
    • 1970-01-01
    • 2021-05-13
    • 2018-10-09
    • 1970-01-01
    • 2013-06-19
    • 1970-01-01
    • 2013-12-16
    • 2021-04-19
    相关资源
    最近更新 更多