使用不同概率的分布进行Python采样

3

我正在尝试实现一个函数,从三个不同的多元高斯分布中返回100个样本。

numpy提供了一种从单个多元高斯分布中采样的方法。但是我找不到一种从三个不同的多元高斯分布中采样且采样概率不同的方法。

我的要求是从以下具有均值和协方差的三个多元高斯分布中以概率$[0.7, 0.2, 0.1]$进行采样:

G_1  mean = [1,1] cov =[ [ 5, 1] [1,5]]
G_2  mean = [0,0] cov =[ [ 5, 1] [1,5]]
G_3  mean = [-1,-1] cov =[ [ 5, 1] [1,5]]

有什么想法吗?
2个回答

4

假设你创建了一个生成器的数组:

generators = [
    np.random.multivariate_normal([1, 1], [[5, 1], [1, 5]]),             
    np.random.multivariate_normal([0, 0], [[5, 1], [1, 5]]), 
    np.random.multivariate_normal([-1, -1], [[5, 1], [1, 5]])]

现在你可以创建一个加权随机生成器索引,因为 np.random.choice 支持加权采样。
draw = np.random.choice([0, 1, 2], 100, p=[0.7, 0.2, 0.1])

(draw 是一个长度为100的数组,每个元素的取值来自于集合 {0, 1, 2},且分别有概率 0.7, 0.2, 0.1。)

现在只需要生成样本:

[generators[i] for i in draw]

1

由于我声望不够,无法对其他答案进行评论,所以我的回答是一种改进方法。

当创建一个列表如 [np.random.multivariate_normal([1, 1], [[5, 1], [1, 5]])] 时,你是从多元正态分布中保留样本,而不是分布本身。因此,每次程序读取相同的 igenerator[i] 时,它会得到完全相同的值。因此,你将得到来自不同分布可能值的离散分布的样本,而不是多元正态分布的混合样本。

一个可行的方法是:

from scipy.stats import multivariate_normal
generators = [
    multivariate_normal([1, 1], [[5, 1], [1, 5]]),
    multivariate_normal([0, 0], [[5, 1], [1, 5]]), 
    multivariate_normal([-1, -1], [[5, 1], [1, 5]])]

现在我们使用来自scipy.stats包的multivariate_normal。与numpy.random中创建样本不同,它创建了一个关于分布的对象,我们可以使用rvs方法从中获取样本。请注意保留HTML标签。
# As before, I create the weighted random list of indeces:
draw = np.random.choice([0, 1, 2], 100, p=[0.7, 0.2, 0.1])
# And then I generate the random values, each one from a different distribuion
[generators[i].rvs() for i in draw]

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