Python Scipy rv_连续错误地从分发中生成样本
上面的代码从0.15到10.1范围内的标准化pdf生成50000个样本。但是,在上限Python Scipy rv_连续错误地从分发中生成样本,python,random,scipy,statistics,Python,Random,Scipy,Statistics,上面的代码从0.15到10.1范围内的标准化pdf生成50000个样本。但是,在上限b=10.1处生成的样本数量过多。这是没有意义的,如打印pdf时所示 如何解决此问题?PDF已针对整个发行版正确规范化。但是,设置a和b只需剪切PDF,而无需重新标准化。使用(a=0.15,b=10.1)PDF不再集成为1,并且通过scipy实现的一个怪癖,剩余密度显然添加到范围的末尾。这导致在上限处有大量样本 我们可以通过绘制a=0和a=0.15的累积密度函数(CDF)来可视化正在发生的情况: from sci
b=10.1
处生成的样本数量过多。这是没有意义的,如打印pdf时所示
如何解决此问题?PDF已针对整个发行版正确规范化。但是,设置
a
和b
只需剪切PDF,而无需重新标准化。使用(a=0.15,b=10.1)
PDF不再集成为1,并且通过scipy实现的一个怪癖,剩余密度显然添加到范围的末尾。这导致在上限处有大量样本
我们可以通过绘制a=0和a=0.15的累积密度函数(CDF)来可视化正在发生的情况:
from scipy import stats
import numpy as np
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)
为了消除CDF中的跳跃和上限范围的虚假样本,我们需要重新规范化a..b范围的PDF。我太懒了,无法分析出正确的因子,所以让scipy来做艰苦的工作:
x = np.linspace(0, 15, 1000)
distribution = your_distribution(a=0.0, b=10.1)
plt.plot(x, distribution.cdf(x), label='a=0')
distribution = your_distribution(a=0.15, b=10.1)
plt.plot(x, distribution.cdf(x), label='a=0.15')
plt.legend()
如果你碰巧知道积分的解析解,你可以用它来代替调用
quad
为什么-1.0*。
这里的代码?@severinpapadeux我不明白这个问题。你的解是有意义的,而且也有效。谢谢@kazemakase。
from scipy import stats
from scipy.integrate import quad
import numpy as np
# I pulled the definition of the PDF out of the class so we can use it to
# compute the scale factor.
def pdf(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)))
class your_distribution(stats.rv_continuous):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# integrate area of the PDF in range a..b
self.scale, _ = quad(pdf, self.a, self.b)
def _pdf(self, x):
return pdf(x) / self.scale # scale PDF so that it integrates to 1 in range a..b
distribution = your_distribution(a=0.15, b=10.1)
sample = distribution.rvs(size=1000)