首页 > 解决方案 > 从多变量正态分布中采样多个元素

问题描述

我有一个大小为 2D 的均值矩阵n*m,其中n是样本m数,是数据的维度。我也有 的n矩阵m*m,即 sigma 是我的形状方差矩阵n*m*m。我希望n从上述分布中抽取样本,例如x_i~N(mean[i], sigma[i]). 有什么方法可以在numpy使用 for 循环的情况下或任何其他标准库中执行此操作吗?

我认为唯一的选择是np.random.multivariate_normal()将均值矩阵展平为一个向量,并将 3D sigma 展平为 2D 块对角矩阵。当然,之后会重塑。但这意味着我们要使用形状为 sigma 的样本,(n*m)*(n*m)它很容易变得非常大,并且只有计算和分配该矩阵(如果可能)可能比在 for 循环中运行花费更长的时间。

在我的具体任务中,现在 Sigma 是所有样本的相同矩阵,这意味着我可以在 中表示 Sigma m*m,并且对于所有 n 个点都是相同的。但我对通用解决方案感兴趣。

感谢你的帮助。

标签: pythonnumpymatrixdistributionnormal-distribution

解决方案


没有可测试的代码很难说,但这应该很接近:

A = numpy.linalg.cholesky(sigma)                # => shape (n, m, m), same as sigma
Z = np.random.normal(size = (n, m))             # shape (n, m)
X = np.einsum('ijk, ik -> ij', A, Z) + mean     # shape (n, m)

这是怎么回事:

我们根据此处概述的标准 Cholesky 分解方法手动采样多元正态分布。 A是这样建造的A@A.T = sigma。然后X(多元法线)可以由 的点积A和单变量法线N(0, 1)向量Z加上mean

在整个计算过程中,您将无关维度保留在第一个(索引 = 0,'i'einsum)轴中,同时收缩最后一个('k')轴,形成点积。


推荐阅读