首页 > 解决方案 > 根据两种不同的分布生成一个样本

问题描述

我想在[0;1000]size 的区间内随机生成一个样本1E4。但遵循两种不同的分布:一种在[0;1]间隔中遵循递增的指数分布,这将产生一个接近于1其他接近的值的基准0[1;1000]然后,在分布之后的间隔中生成我的样本的第二部分1/r

我认为更简单的方法是将全局样本分成两个不同的样本。但我不知道如何处理它。我试图使用图书馆的一些分布,scipy但我没有找到一种方法来正确使用它们来生成我的全局样本。你怎么看?

标签: pythonpython-3.xprobability

解决方案


您可以使用两个单独的分布,但您需要确保样本数在边界点 ( r == 1) 处匹配。因此,您需要估计左 (exp) 和右 (1/r) 分布所需的样本数。两个分布的积分如下:

这意味着左分布的概率r = 1exp(1) / 1.7183,而右分布的概率是1 / 6.9078。所以这给出了一个比率ratio = left / right = 10.928。这意味着您需要ratio在右侧间隔中生成比左侧多倍的值,以便最终在边界处获得相同数量的样本。假设您想N总共生成样本,这意味着您需要N1 = N / (ratio + 1)在左侧 (exp) 间隔中生成样本,N2 = N * ratio / (ratio + 1)在右侧 (1/r) 区间中生成样本。

所以这里有一些示例代码:

import matplotlib.pyplot as plt
import numpy as np

r_max = 1000.0
integral_1 = np.exp(1.0) - 1.0  # 1.7183
integral_2 = np.log(r_max)      # 6.9078

N = 2_000_000  # total number of samples
ratio = np.exp(1.0) / integral_1 * integral_2  # 10.928
N1 = int(N / (ratio + 1))
N2 = int(N * ratio / (ratio + 1))

# Use inverse transform sampling in the following.
s1 = np.log(integral_1 * np.random.random(size=N1) + 1.0)
s2 = np.exp(integral_2 * np.random.random(size=N2))

samples = np.concatenate((s1, s2))
np.random.shuffle(samples)  # optionally shuffle the samples

plt.hist(samples, bins=int(20 * r_max))
plt.xlim([0, 5])
plt.show()

产生以下分布:

示例分布


推荐阅读