初始化 Python 自定义分发
Initialize Python Custom Distribution
我在 Scipy 中使用自定义对数伽玛分布,我想将它与各种预定义的 Scipy 分布一起使用。我的问题是自定义分发似乎需要与预定义分发有点不同的处理方式。具体来说,似乎我需要先初始化自定义分发才能使用。见下文:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.stats import gamma
from scipy.special import gamma as gamma_func
from scipy.special import erf, erfinv
from scipy.stats import rv_continuous
from scipy.stats import lognorm, norm
class custom_lgamma(rv_continuous):
"""
pdf defined on page 227 in the book https://www.amazon.com/Loss-Distributions-Wiley-Probability-Statistics/dp/0471879290
The parameters of this distribution are a and lambdax
"""
dist_name = "Custom_Log_Gamma"
def _pdf(self, x, a, lambdax):
""" pdf of the log gamma function """
return (lambdax**(a)*(np.log(x))**(a-1))/(x**(lambdax+1)*gamma_func(a))
def _cdf(self, x, a, lambdax):
""" cdf of the log gamma function """
u = lambdax*np.log(x)
return gamma.cdf(u, a=a)
def _sf(self, x, a, v):
""" survivial fuction of the log gamma function. This is 1 - CDF. """
u = lambdax*np.log(x)
return 1 - gamma.cdf(u, a=a)
def _ppf(self,x, a, lambdax):
""" inverse cdf of the log gamma function. This is required to conduct efficient random variable simulation. """
u = gamma.ppf(x, a=a)
return np.exp(u/lambdax)
def _argcheck(self, a, lambdax):
""" check that the fitted parameters fall within the required bounds """
param1_test = a > 0
param2_test = lambdax > 0
return param1_test and param2_test
test_data2 = custom_lgamma().rvs(a=5,lambdax=3,size=1000)
lg = custom_lgamma()
lg.fit(test_data2,floc=0,fscale=1)
custom_lgamma().fit(test_data2,floc=0,fscale=1)
这两种实现都有效,但是,我希望能够使用自定义分布而无需对其进行初始化,类似于预定义分布的使用方式:
norm.fit(test_data2)
预定义分布不需要初始化或可调用。如果我尝试以这种方式使用自定义分发,我会得到结果:
custom_lgamma.fit(test_data2,floc=0,fscale=1)
>>>
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-47-9b87a6428141> in <module>
----> 1 custom_lgamma.fit(test_data2,floc=0,fscale=1)
TypeError: fit() missing 1 required positional argument: 'data'
有没有办法定义自定义 scipy 分布,使其不需要初始化或可调用?我的 scipy 是 1.5.2。谢谢!
您没有初始化您的分发; SciPy 的分发基础设施就是这样构建的。您对 rv_continuous
class 和 rv_frozen
class.
的实例感到困惑
当您调用您的发行版 class(在您的情况下为 custom_lgamma
)时,SciPy 会为用户界面生成文档和代码,从而创建我们从 [= 中看到和使用的发行版14=](例如 norm
、gamma
)(这是当您执行 custom_lgamma()
时发生的情况)。此实例包含 pdf
、cdf
等方法,这些方法使用形状参数 调用 (就像其他 scipy.stats
分布一样)。
再次调用此实例(例如 norm()
)将创建一个 frozen 分布(rv_frozen
class 的一个实例)其形状参数无法更改(如果您再次调用 custom_lgamma
实例或执行 custom_lgamma()()
就会发生这种情况)。此实例具有仅接受分位数参数的 pdf
方法。
这是 SciPy 使用的约定:
class custom_lgamma_gen(rv_continuous):
# implement your distribution methods here.
....
# this is the instance containing user interface of the distribution.
custom_lgamma = custom_lgamma_gen(name="custom_lgamma")
# now, you can call the fit method just like you would
# do with other scipy.stats distributions.
custom_lgamma.fit(test_data2,floc=0,fscale=1)
# to create a frozen distribution, do:
custom_lgamma_frozen = custom_lgamma()
# now you can call the methods without shape parameters
custom_lgamma_frozen.pdf(0.5)
我在 Scipy 中使用自定义对数伽玛分布,我想将它与各种预定义的 Scipy 分布一起使用。我的问题是自定义分发似乎需要与预定义分发有点不同的处理方式。具体来说,似乎我需要先初始化自定义分发才能使用。见下文:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from scipy.stats import gamma
from scipy.special import gamma as gamma_func
from scipy.special import erf, erfinv
from scipy.stats import rv_continuous
from scipy.stats import lognorm, norm
class custom_lgamma(rv_continuous):
"""
pdf defined on page 227 in the book https://www.amazon.com/Loss-Distributions-Wiley-Probability-Statistics/dp/0471879290
The parameters of this distribution are a and lambdax
"""
dist_name = "Custom_Log_Gamma"
def _pdf(self, x, a, lambdax):
""" pdf of the log gamma function """
return (lambdax**(a)*(np.log(x))**(a-1))/(x**(lambdax+1)*gamma_func(a))
def _cdf(self, x, a, lambdax):
""" cdf of the log gamma function """
u = lambdax*np.log(x)
return gamma.cdf(u, a=a)
def _sf(self, x, a, v):
""" survivial fuction of the log gamma function. This is 1 - CDF. """
u = lambdax*np.log(x)
return 1 - gamma.cdf(u, a=a)
def _ppf(self,x, a, lambdax):
""" inverse cdf of the log gamma function. This is required to conduct efficient random variable simulation. """
u = gamma.ppf(x, a=a)
return np.exp(u/lambdax)
def _argcheck(self, a, lambdax):
""" check that the fitted parameters fall within the required bounds """
param1_test = a > 0
param2_test = lambdax > 0
return param1_test and param2_test
test_data2 = custom_lgamma().rvs(a=5,lambdax=3,size=1000)
lg = custom_lgamma()
lg.fit(test_data2,floc=0,fscale=1)
custom_lgamma().fit(test_data2,floc=0,fscale=1)
这两种实现都有效,但是,我希望能够使用自定义分布而无需对其进行初始化,类似于预定义分布的使用方式:
norm.fit(test_data2)
预定义分布不需要初始化或可调用。如果我尝试以这种方式使用自定义分发,我会得到结果:
custom_lgamma.fit(test_data2,floc=0,fscale=1)
>>>
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-47-9b87a6428141> in <module>
----> 1 custom_lgamma.fit(test_data2,floc=0,fscale=1)
TypeError: fit() missing 1 required positional argument: 'data'
有没有办法定义自定义 scipy 分布,使其不需要初始化或可调用?我的 scipy 是 1.5.2。谢谢!
您没有初始化您的分发; SciPy 的分发基础设施就是这样构建的。您对 rv_continuous
class 和 rv_frozen
class.
当您调用您的发行版 class(在您的情况下为 custom_lgamma
)时,SciPy 会为用户界面生成文档和代码,从而创建我们从 [= 中看到和使用的发行版14=](例如 norm
、gamma
)(这是当您执行 custom_lgamma()
时发生的情况)。此实例包含 pdf
、cdf
等方法,这些方法使用形状参数 调用 (就像其他 scipy.stats
分布一样)。
再次调用此实例(例如 norm()
)将创建一个 frozen 分布(rv_frozen
class 的一个实例)其形状参数无法更改(如果您再次调用 custom_lgamma
实例或执行 custom_lgamma()()
就会发生这种情况)。此实例具有仅接受分位数参数的 pdf
方法。
这是 SciPy 使用的约定:
class custom_lgamma_gen(rv_continuous):
# implement your distribution methods here.
....
# this is the instance containing user interface of the distribution.
custom_lgamma = custom_lgamma_gen(name="custom_lgamma")
# now, you can call the fit method just like you would
# do with other scipy.stats distributions.
custom_lgamma.fit(test_data2,floc=0,fscale=1)
# to create a frozen distribution, do:
custom_lgamma_frozen = custom_lgamma()
# now you can call the methods without shape parameters
custom_lgamma_frozen.pdf(0.5)