如何解决如何最好地从截断的正态分布中获取样本?
我已经进行了一些搜索,但似乎无法找到一种合理的方法来从截断的正态分布中进行采样。
我没有被截断:
samples = [np.random.normal(loc=x,scale=d) for (x,d) in zip(X,D)]
X
和D
是浮点列表。
目前,我正在像这样实现截断:
def truncnorm(loc,scale,bounds):
s = np.random.normal(loc,scale)
if s > bounds[1]:
return bounds[1]
elif s < bounds[0]:
return bounds[0]
return s
samples = [truncnorm(loc=x,scale=d,bounds=b) for (x,d,b) in zip(X,D,bounds)]
bounds
是元组列表(min,max)
解决方法
返回它们之外的样本的边界值,将导致过多的样本落在边界上。这并不代表实际的分布。边界上的值需要被拒绝,并用新的样本替换。这样的代码可能是:
def test_truncnorm(loc,scale,bounds):
while True:
s = np.random.normal(loc,scale)
if bounds[0] <= s <= bounds[1]:
break
return s
在狭窄范围内,这可能会非常慢。 Scipy的truncnorm更有效地处理了这种情况。出乎意料的是,边界以标准法线的功能表示,因此您的调用将是:
s = scipy.stats.truncnorm.rvs((bounds[0]-loc)/scale,(bounds[1]-loc)/scale,loc=loc,scale=scale)
请注意,使用numpy的vectorization and broadcasting时scipy的工作速度更快。一旦您习惯了这种记号,它的书写和阅读也将变得更加简单。所有样本可以一口气计算出来:
X = np.array(X)
D = np.array(D)
bounds = np.array(bounds)
samples = scipy.stats.truncnorm.rvs((bounds[:,0] - X) / D,(bounds[:,1] - X) / D,loc=X,scale=D)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。