截断SciPy随机分布

5

有没有人对高效截断SciPy随机分布有建议?例如,如果我像下面这样生成随机值:

import scipy.stats as stats
print stats.logistic.rvs(loc=0, scale=1, size=1000)

我该如何在不改变分布的原始参数和样本大小的情况下,将输出值限制在0和1之间,并同时最小化机器的工作量?

3个回答

8

您的问题更多是一个统计学问题,而不是一个scipy问题。一般来说,您需要能够对您感兴趣的区间进行归一化,并通过解析方法计算该区间的CDF以创建高效的抽样方法。编辑:事实证明这是可能的(不需要拒绝抽样):

import scipy.stats as stats

import matplotlib.pyplot as plt
import numpy as np
import numpy.random as rnd

#plot the original distribution
xrng=np.arange(-10,10,.1)
yrng=stats.logistic.pdf(xrng)
plt.plot(xrng,yrng)

#plot the truncated distribution
nrm=stats.logistic.cdf(1)-stats.logistic.cdf(0)
xrng=np.arange(0,1,.01)
yrng=stats.logistic.pdf(xrng)/nrm
plt.plot(xrng,yrng)

#sample using the inverse cdf
yr=rnd.rand(100000)*(nrm)+stats.logistic.cdf(0)
xr=stats.logistic.ppf(yr)
plt.hist(xr,density=True)

plt.show()

两个问题:您可以直接使用logistic.cdf而不是integrate.quad,lst = xr [yr <stats.logistic.pdf(xr)]可以进行矢量化而不是使用Python列表推导。 - Josef
是的,那些都是好观点,但实际上事实证明还有更好的解决方案...请参见编辑。 - user1149913
Logistic回归中对于ppf有一个不错的表达方式,通过ppf转换均匀随机变量会更好,但我很喜欢你针对ppf计算昂贵情况下提供的拒绝抽样方案。 - Josef
这可以在给定的参数下完成吗?我不明白在logistic.rvs()函数中分布的参数是在哪里改变的。 - Uis234

0
您可以将结果归一化为最大返回值:
>>> dist = stats.logistic.rvs(loc=0, scale=1, size=1000)
>>> norm_dist = dist / np.max(dist)

这将保持“形状”不变,并且值介于01之间。但是,如果您从分布中进行重复抽样,请确保将所有抽样归一化为相同的值(来自所有抽样的最大值)。

然而,如果您正在进行此类操作,您需要非常小心,以确保它在您尝试实现的上下文中有意义(我没有足够的信息来发表评论...)


非常抱歉 - 我表达不够清楚(我更新了问题)。我的意思不是“形状”,而是“原始参数”。此外,我认为这(对于某些分布)可能具有与更改比例参数相同的效果。 - TimY

0
你想要实现什么目标?根据定义,逻辑分布具有无限范围。如果以任何方式截断结果,它们的分布将会改变。如果你只是想要在范围内生成随机数,可以使用random.random()

我只是举了逻辑回归作为例子,但有些情况下,现实世界的分布几乎与理论分布完全相同,但由于某些外部限制,无法真实地超过某个特定值。在许多情况下,截断可能只会增加微小误差,可以被视为建模中可以忽略的。如果您还不确定,我认为最好将其视为纯粹的理论练习。 - TimY

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接