从多变量正态分布中抽样一个以上的元素
Sample more than one element from multivariable normal distribution
我有一个大小为 n*m
的二维均值矩阵,其中 n
是样本数,m
是数据的维度。
我还有 n
个 m*m
的矩阵,即 sigma 是我的 n*m*m
形状的方差矩阵。
我希望从上面的分布中抽取 n
个样本,这样 x_i~N(mean[i], sigma[i])
。
在 numpy
或任何其他标准库 w/o 运行 for 循环中有什么方法可以做到这一点?
我认为唯一的选择是使用 np.random.multivariate_normal()
将均值矩阵展平为一个向量,并将 3D sigma 展平为 2D 块对角矩阵。当然,之后要重塑。但这意味着我们将使用形状为 (n*m)*(n*m)
的 sigma 样本,这很容易变得非常大,并且仅计算和分配该矩阵(如果可能)可能比 for 循环中的 运行 花费更长的时间。
在我的特定任务中,现在 Sigma 是所有样本的相同矩阵,这意味着我可以在 m*m
中表示 Sigma,并且它对于所有 n 个点都是相同的。但我对通用解决方案感兴趣。
感谢您的帮助。
没有可测试的代码很难判断,但这应该很接近:
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 分解方法手动对多元正态分布进行采样 here。 A
的构建使得 A@A.T = sigma
。然后 X
(多元正态)可以由 A
和单变量正态 N(0, 1) 向量 Z
的点积形成, 加上 mean
.
你在第一个(index = 0,'i'
in the einsum
)轴的整个计算过程中保持无关维度,同时收缩最后一个('k'
)轴,形成点积。
我有一个大小为 n*m
的二维均值矩阵,其中 n
是样本数,m
是数据的维度。
我还有 n
个 m*m
的矩阵,即 sigma 是我的 n*m*m
形状的方差矩阵。
我希望从上面的分布中抽取 n
个样本,这样 x_i~N(mean[i], sigma[i])
。
在 numpy
或任何其他标准库 w/o 运行 for 循环中有什么方法可以做到这一点?
我认为唯一的选择是使用 np.random.multivariate_normal()
将均值矩阵展平为一个向量,并将 3D sigma 展平为 2D 块对角矩阵。当然,之后要重塑。但这意味着我们将使用形状为 (n*m)*(n*m)
的 sigma 样本,这很容易变得非常大,并且仅计算和分配该矩阵(如果可能)可能比 for 循环中的 运行 花费更长的时间。
在我的特定任务中,现在 Sigma 是所有样本的相同矩阵,这意味着我可以在 m*m
中表示 Sigma,并且它对于所有 n 个点都是相同的。但我对通用解决方案感兴趣。
感谢您的帮助。
没有可测试的代码很难判断,但这应该很接近:
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 分解方法手动对多元正态分布进行采样 here。 A
的构建使得 A@A.T = sigma
。然后 X
(多元正态)可以由 A
和单变量正态 N(0, 1) 向量 Z
的点积形成, 加上 mean
.
你在第一个(index = 0,'i'
in the einsum
)轴的整个计算过程中保持无关维度,同时收缩最后一个('k'
)轴,形成点积。