python - 从多变量正态分布中采样多个元素
问题描述
我有一个大小为 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 个点都是相同的。但我对通用解决方案感兴趣。
感谢你的帮助。
解决方案
没有可测试的代码很难说,但这应该很接近:
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'
)轴,形成点积。
推荐阅读
- angular - 异步/等待和服务更新
- python - 如何从网站中提取链接并使用python在网络抓取中提取其内容
- gem5 - 主机没有 libpng 库
- r - 如何计算 R 中最短和最长的时间间隔?
- java - 将 JSON 转换为 POJO 并在必填字段为空值的情况下抛出异常
- alert - Splunk:限制警报
- tfs - 将项目从 VS2013 添加到 AzureDevOps
- python - 我已经编写了这个 Python 代码来将 HTTP Post 发送到 NLP,然后保存结果
- python - 检查文件是否在子目录中?
- reactjs - 当 useRef Div 宽度改变时更新 UI