生成遵循两种不同分布的一个样本

Generate one sample following two different distributions

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

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

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

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

下面是一些示例代码:

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()

产生以下分布: