【发布时间】:2020-06-25 09:33:33
【问题描述】:
在this post 之后,我尝试通过创建LogitNormal 类来创建logit 正态分布:
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import logit
from scipy.stats import norm, rv_continuous
class LogitNormal(rv_continuous):
def _pdf(self, x, **kwargs):
return norm.pdf(logit(x), **kwargs)/(x*(1-x))
class OtherLogitNormal:
def pdf(self, x, **kwargs):
return norm.pdf(logit(x), **kwargs)/(x*(1-x))
fig, ax = plt.subplots()
values = np.linspace(10e-10, 1-10e-10, 1000)
sigma, mu = 1.78, 0
ax.plot(
values, LogitNormal().pdf(values, loc=mu, scale=sigma), label='subclassed'
)
ax.plot(
values, OtherLogitNormal().pdf(values, loc=mu, scale=sigma),
label='not subclassed'
)
ax.legend()
fig.show()
但是,LogitNormal 类不会产生预期的结果。当我不继承 rv_continuous 时,它可以工作。这是为什么?我需要子类化才能工作,因为我还需要它附带的其他方法,例如rvs。
顺便说一句,我在 Python 中创建自己的 logit 正态分布的唯一原因是因为我能找到的该分布的唯一实现来自 PyMC3 package 和 TensorFlow package,两者都很重/ 如果你只需要它们来完成那一项功能,那就大材小用了。我已经尝试过PyMC3,但显然它不适用于scipy,我想,它总是让我崩溃。但这是一个完全不同的故事。
【问题讨论】:
-
你为什么打电话给
LogitNormal().pdf?我想你应该打电话给LogitNormal()._pdf。因为_pdf是您在LogitNormal类中调用唯一方法的方式。 -
因为重新定义
_pdf或_cdf是您根据文档 docs.scipy.org/doc/scipy/reference/generated/… 以及我在问题中链接的帖子对rv_continuous进行子类化的方式。 -
根据源码
rv_continuous.pdf方法使用loc和scale参数对x值进行转换。我猜你会得到与默认值相同的结果:sigma, mu = 1, 0. -
我愿意。我糊涂了。这是什么意思?
-
假设问题源于双重计算。
rv_continuous.pdf计算概率密度函数。scipy.stats.norm.pdf计算概率密度函数。我想这就是我能说的全部,因为我不熟悉这些功能。祝你好运。
标签: python scipy statistics distribution