在Python中从双变量正态分布取样

4 投票
3 回答
9915 浏览
提问于 2025-04-17 09:14

我想创建两个相互关联的随机变量,我觉得最好的方法是从一个有两个变量的正态分布中抽取数据,使用一些特定的参数(当然也欢迎其他的想法)。没有关联的版本看起来是这样的:

import numpy as np
sigma = np.random.uniform(.2, .3, 80)
theta = np.random.uniform( 0, .5, 80)

不过,对于这80次抽样中的每一次,我希望sigma值和theta值有关系。你们有什么想法吗?

3 个回答

0

这两个正态分布是通过一个平均值和一个方差来定义的:

means = [0, 0] # respective means
var_xx = 1 ** 2 # var x = std x squared
var_yy = 1 ** 2

这两个分布之间的协方差是通过一个协方差矩阵来定义的,这个矩阵由方差和两个协方差组成。两个协方差 x/y 和 y/x 是相等的:

import numpy as np
cov_xy = 0.5
cov = np.array([[var_xx, cov_xy],
                [cov_xy, var_yy]])

我们使用随机生成器和函数 multivariate_normal 从这些分布中抽取 N 对数据。可选的 check_valid='raise' 用来检查协方差矩阵是否真的 是对称的并且是半正定的

g = np.random.default_rng()
N = 100
pairs = g.multivariate_normal(means, cov, size=N, check_valid='raise')

举个例子,我们来绘制这些数据对:

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter(pairs[:,0], pairs[:,1])

在这里输入图片描述

3

可以使用import multivariate_normalscipy库中导入。假设我们创建了随机变量xy

from scipy.stats import multivariate_normal

rv_mean = [0, 1]  # mean of x and y  
rv_cov = [[1.0,0.5], [0.5,2.0]]  # covariance matrix of x and y
rv = multivariate_normal.rvs(rv_mean, rv_cov, size=10000)

你可以从rv[:,0]中得到x,从rv[:,1]中得到y。相关系数可以通过以下方式获得:

import numpy as np
np.corrcoef(rv.T)
12

使用内置功能: http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.multivariate_normal.html

>>> import numpy as np
>>> mymeans = [13,5]  
>>> # stdevs = sqrt(5),sqrt(2)
>>> # corr = .3 / (sqrt(5)*sqrt(2) = .134
>>> mycov = [[5,.3], [.3,2]]   
>>> np.cov(np.random.multivariate_normal(mymeans,mycov,500000).T)
array([[ 4.99449936,  0.30506976],
       [ 0.30506976,  2.00213264]])
>>> np.corrcoef(np.random.multivariate_normal(mymeans,mycov,500000).T)
array([[ 1.        ,  0.09629313],
       [ 0.09629313,  1.        ]])
  1. 如上所示,如果你需要调整非单位方差,事情会变得有点复杂。
  2. 更多参考资料: http://www.riskglossary.com/link/correlation.htm
  3. 为了在现实世界中有意义,协方差矩阵必须是对称的,并且还必须是正定的半正定的(也就是说,它必须是可逆的)。某些反相关的结构可能无法实现。

撰写回答