生成遵循两种不同分布的一个样本
Generate one sample following two different distributions
我想在 [0;1000]
区间内随机生成一个大小为 1E4
的样本。但遵循两种不同的分布:一种在 [0;1]
区间内,遵循递增的指数分布,相对于其他接近 0
的值,将生成接近 1
的一组值。然后,在 1/r
分布之后的 [1;1000]
区间内生成样本的第二部分。
我认为更简单的方法是将全局样本分成两个不同的样本。但我不知道如何处理它。我尝试使用 scipy
库的一些分布,但我没有找到正确使用它们来生成我的全局样本的方法。你怎么看?
您可以使用两个单独的分布,但您需要确保样本数量在边界点 (r == 1
) 匹配。因此,您需要估计左 (exp) 和右 (1/r) 分布所需的样本数。两个分布的积分如下:
- integrate exp(r) from 0 to 1:
exp(1) - 1 == 1.7183
- integrate 1/r from 1 to 1000:
log(1000) == 6.9078
这意味着左分布在 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()
产生以下分布:
我想在 [0;1000]
区间内随机生成一个大小为 1E4
的样本。但遵循两种不同的分布:一种在 [0;1]
区间内,遵循递增的指数分布,相对于其他接近 0
的值,将生成接近 1
的一组值。然后,在 1/r
分布之后的 [1;1000]
区间内生成样本的第二部分。
我认为更简单的方法是将全局样本分成两个不同的样本。但我不知道如何处理它。我尝试使用 scipy
库的一些分布,但我没有找到正确使用它们来生成我的全局样本的方法。你怎么看?
您可以使用两个单独的分布,但您需要确保样本数量在边界点 (r == 1
) 匹配。因此,您需要估计左 (exp) 和右 (1/r) 分布所需的样本数。两个分布的积分如下:
- integrate exp(r) from 0 to 1:
exp(1) - 1 == 1.7183
- integrate 1/r from 1 to 1000:
log(1000) == 6.9078
这意味着左分布在 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()
产生以下分布: