如何从标准正态值生成多元正态分布?
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.
我需要仅使用随机值生成器而不使用 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.