AI算法Python实现:Random Multivariate Normal Vectors

一、算法原理

1.1 随机向量

随机向量是定义在同一空间上的随机变量的列表。我们一般用一个n\times 1的向量来表示。

X=\begin{bmatrix} X_{1}\\ X_{2}\\ ...\\ X_{n} \end{bmatrix}

X的平均值向量为\mu =\left [ \mu _{1} \mu _{2}...\mu _{n} \right ]^{T},其中\mu _{i}=E(X_{i})

X的协方差矩阵为ZZ_{(i, j)}=Cov(X_{i}, X_{j})

1.2 线性变换

Y=AX+b

被称为对X进行线性变换。其中,Y是一个m\times n的矩阵,b是一个n\times 1的向量。

在线性变换过程中,我们可以得到:

\mu _{Y}=A\mu +b

Z_{Y}=AZA^{T}

根据协方差矩阵的性质,矩阵Z_{Y}对称,并且主对角线上的元素都得非负,这意味着AZA^{T}\geqslant 0,即协方差矩阵半正定。

1.3 多元正态分布向量

如果X向量中的元素都独立同分布于标准正态分布,那么Y可以称之为多元正态分布向量,则\mu为零向量,Z为单位矩阵。如果我们要根据平均值向量和协方差矩阵来生成多元正态分布向量的话,根据

Y=AX+b

 我们令b为平均值向量,根据

Z_{Y}=AA^{T}

 解出A,便可以计算出随机多元正态分布向量了。

二、代码实现

  • MVN.py
  • main.py

MVN.py

import numpy as np


class MVN:
    def __init__(self, mean, cov, size=None):
        """
        generate  multivariate normal random vectors
        :param mean: list[int], mean of components of the vector in the distribution we need
        :param cov: list[list[int]], covariance matrix of the distribution we need
        :param size:  int or tuple of ints, shape of the output
        """
        self.mean = mean
        self.cov = cov
        if size is None:
            self.size = len(mean)
        elif type(size) == int:
            self.size = (size,) + (len(mean),)
        else:
            self.size = size + (len(mean),)

    def _preprocess_mean(self):
        if self.mean.shape[0] != 1:
            self.mean.reshape(1, -1)

    @staticmethod
    def Cholesky(matrix):
        w = matrix.shape[0]
        G = np.zeros((w, w))
        for i in range(w):
            G[i, i] = (matrix[i, i] - np.dot(G[i, :i], G[i, :i].T)) ** 0.5
            for j in range(i + 1, w):
                G[j, i] = (matrix[j, i] - np.dot(G[j, :i], G[i, :i].T)) / G[i, i]
        return G

    def _preprocess_cov(self):
        if self.cov.shape[0] != self.cov.shape[1]:
            raise
        eigenvalue, _ = np.linalg.eig(self.cov)
        for i in eigenvalue:
            if i < 0:
                raise

    def get_vector(self):
        Z = np.random.standard_normal(self.size)
        vector = np.random.normal(self.mean, 0, self.size)
        A = self.Cholesky(np.array(self.cov))
        X = np.matmul(Z, A.T) + vector
        return X

main.py

from MVN import MVN


a = MVN([1, 2, 3], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], (1, 2, 3))
c = a.get_vector()
print(c)
print(c.shape)

运行结果:

三、参考资料

1. Random Multivariate Normal Vectors

2. Data 140 Textbook (23.2. Multivariate Normal Vectors)

3. 如何直观地理解「协方差矩阵」?

4. numpy.random.multivariate_normal文档

5. 基于Python实现的Cholesky分解与Crout分解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值