Tay*_*lor 3 python simulation numpy
在我正在编写的Python脚本中,我正在使用表达式模拟多元正态随机向量
np.random.multivariate_normal(np.zeros(dim_obs), y_cov)
Run Code Online (Sandbox Code Playgroud)
我的脚本运行,但会生成以下警告:
RuntimeWarning: covariance is not positive-semidefinite.
Run Code Online (Sandbox Code Playgroud)
我投入的小调试打印语句False大部分都是打印出来的
print( np.all(np.linalg.eigvals(y_cov) > 0) )
Run Code Online (Sandbox Code Playgroud)
为什么这会引发误报?我y_cov是正半正定因为它是(抱歉缺少TeX标记)B x x'B'+ yy'其中B是矩阵,其他是随机向量,每个元素为正.
在这个特定的运行中,B实际上只是一个大小为9的向量.我可以忽略这个警告吗?从文档:
注意,协方差矩阵必须是正半定的(也就是非负定的).否则,此方法的行为未定义,并且无法保证向后兼容性.
编辑:这是一个完全可以运行的东西.感谢您提示@ user2357112.
import numpy as np
num_factors = 1
dim_obs = 9
u = np.random.normal(size = num_factors)
v = np.random.normal(size = dim_obs)
y_cov = np.dot(np.ones((9,1)), np.exp(u.reshape((num_factors,1))/2))
y_cov = np.dot(y_cov, np.exp(u.reshape((1,num_factors))/2)) #transpose
y_cov = np.dot(y_cov, np.transpose(np.ones((9,1))))
y_cov += np.dot(np.exp( v.reshape((dim_obs,1)) / 2),
np.exp( v.reshape((1,dim_obs)) / 2))
print( np.random.multivariate_normal(np.zeros(dim_obs), y_cov) )
print( np.all(np.linalg.eigvals(y_cov) > 0) )
print( np.linalg.eigvals(y_cov) )
Run Code Online (Sandbox Code Playgroud)
小智 10
从理论上讲,你的矩阵是半正定的,有几个特征值恰好为零.但是浮点数的计算引入了截断误差,导致这些特征值中的一些非常小而是负的 ; 因此,矩阵不是半正的.
目前,警告可能会被忽略; 但NumPy文档说非psd情况下的行为是未定义的,所以我不想依赖于此.纠正浮点错误的一种方法是添加单位矩阵的微小倍数y_cov.例如,像这样:
min_eig = np.min(np.real(np.linalg.eigvals(y_cov)))
if min_eig < 0:
y_cov -= 10*min_eig * np.eye(*y_cov.shape)
Run Code Online (Sandbox Code Playgroud)
添加固定倍数的身份,如1e-12,将适用于所有合理大小的矩阵,但仍然无关紧要的结果.
为了完整性,一种更简单的方法来重现该问题:
import numpy as np
x = np.random.normal(size=(5,))
y = np.outer(x, x)
z = np.random.multivariate_normal(np.zeros(5), y)
Run Code Online (Sandbox Code Playgroud)
这会引发相同的警告(很有可能).
在您的情况下,生成高斯样本的一种更有效的方法(也不受@zaq识别的数值问题的影响)是观察到协方差矩阵等于a*a.T + b*b.T(a,b:列向量)的多元零均值高斯随机向量是在分布上等于随机向量a*w1 + b*w2,其中w1和w2是均值为零且方差为零的独立高斯标量随机变量1
| 归档时间: |
|
| 查看次数: |
7362 次 |
| 最近记录: |