python - 即使对于具有二维高斯的大样本量,样本协方差矩阵也与事实相去甚远
问题描述
这是一个非常简单的脚本,可以生成 10000 个点的 2D 高斯分布。np.cov 估计的协方差矩阵似乎与生成的矩阵相去甚远。解释是什么,有解决方案吗?
import numpy as np
import matplotlib.pyplot as plt
center=[0,0]
npoints=10000
data_covmat = np.array([[1,1],[1,0.5]])
lines=np.random.multivariate_normal(center,data_covmat,npoints)
print(f'2D gaussian centered at {center}, {npoints} points\nCovariance matrix =')
print(data_covmat)
plt.scatter(lines[:,0],lines[:,1],alpha=.1)
plt.axis('scaled')
plt.show()
print(f'Sample covariance matrix =\n{np.cov(lines,rowvar=False)}')
协方差矩阵 =
[[1。1.] [1. 0.5]]
样本协方差矩阵 =
[[1.23880367 0.74585136] [0.74585136 0.85974812]]
解决方案
数组 [[1, 1], [1, 0.5]] 不是半正定的。它的特征值之一是负数。cov
文档字符串中对参数的描述multivariate_normal
说“分布的协方差矩阵。它必须是对称的和半正定的,才能正确采样。”
试试,比如说,[[1, 0.6], [0.6, 0.5]],它是对称的和正定的,它按预期工作:
In [37]: npoints = 10000
In [38]: center = [0, 0]
In [39]: data_covmat = np.array([[1, 0.6], [0.6, 0.5]])
In [40]: np.linalg.eigvals(data_covmat)
Out[40]: array([1.4, 0.1])
In [41]: lines = np.random.multivariate_normal(center, data_covmat, npoints)
In [42]: np.cov(lines, rowvar=False)
Out[42]:
array([[0.99782727, 0.60349542],
[0.60349542, 0.50179535]])
推荐阅读
- php - 用于根据简码属性去除自定义字段标签的简码
- android - ExtendedFloatingActionButton - 图标重力设置为文本结束但图标不在中心时尖叫
- python - 按月和年对熊猫的数据框系列进行排序?
- mysql - 你可以将多值索引与范围扫描结合起来吗
- dialogflow-es - 有没有办法在用户被定向到网页后将用户重定向到谷歌助手操作中的同一会话
- android - 如何处理 Kotlin 中的递归和嵌套数据类
- android - 在 Cordova 应用程序中检测首选语言顺序
- asp.net-mvc - 如何在 MVC 中更改 ASP.NET_SessionId cookie 路径
- mysql - 多选用户名SQL
- git - 想要在 Azure 构建管道中将 Git 提交详细信息设置为构建标题/定义