如何从标准正态值生成多元正态分布?

How to generate multivariate Normal distribution from a standard normal value?

我需要仅使用随机值生成器而不使用 scipy 或 numpy 生成器来生成多元正态分布。

我需要生成以下内容

这是我的尝试

V = np.array([
    [1, 2], 
    [2, 5]])
B = np.linalg.cholesky(V)
A = np.array([1,2])

# norm() return one number from standard normal distribution 
n1 = np.array([norm() for _ in range(40)])
n2 = np.array([norm() for _ in range(40)])
np.array([n1,n2]).T.dot(B) + A

在这里,我使用 Cholesky 分解作为 in this post

但是,我认为这是不正确的。

您的代码几乎是正确的,但您可以检查您的数字是否没有所需的协方差 属性,如果您应用 numpy's cov 函数:

res = np.array([n1,n2]).T.dot(B) + A
np.cov(res.T).round()
# returns ~ 
# array([[5., 2.],
#        [2., 1.]])

请注意,与所需值相比,元素 1,1 和 2,2 已交换。

要利用 numpy 的 CPU-向量化矩阵乘法,您使用 numpy's dot function. You properly arranged the N pieces of 2D input vectors Z into a Nx2 dimensional vector np.array([n1,n2]).T. But as you pointed out in the Cholesky decomposition and variance 问题,Z 值必须从左侧乘以 B,并且您还想将其合并到dot函数的广播规则,问题出在这里。代码 np.array([n1,n2]).T.dot(B) 从右边而不是左边乘以 Z(的数组)。要计算 B 的左积,您需要使用 dot(B.T)

此示例还表明协方差矩阵具有正确的形式

import random
import numpy as np

random.seed(0)
N=10000

V = np.array([
    [1, 2],
    [2, 5]])
B = np.linalg.cholesky(V)
A = np.array([1, 2])

# norm() return one number from standard normal distribution
n1 = np.array([random.gauss(0, 1) for _ in range(10000)])
n2 = np.array([random.gauss(0, 1) for _ in range(10000)])
res = np.array([n1, n2]).T.dot(B.T) + A

np.cov(res.T).round()
# returns ~  array([[1., 2.],
#                   [2., 5.]])

如图。下面绘制了随机点,以及协方差矩阵的特征向量及其特征值的平方根长度,如 Wikipedia.