如何基于Cholesky分解从生成数据集还原初始协方差矩阵?
问题描述
想要基于Cholesky分解复现变量相关变换,已知协方差矩阵满足C = L@L.T,尝试从标准正态分布生成服从给定协方差矩阵sigma = [[9,1],[1,1]]的数据,但生成的样本协方差无法还原初始矩阵,当前代码输出的协方差为:
[[86.66333557 10.85423541] [10.85423541 2.1026003 ]]
错误原因分析
- Cholesky分解的变换逻辑错误:生成服从
N(0, sigma)的数据,正确方式是用Cholesky分解得到的下三角矩阵(或上三角矩阵)直接左乘标准正态样本。原代码中先通过U.dot(...)生成数据,再用L=U.T再次左乘,相当于做了两次变换,最终协方差变为U.T@U@U.T@U = sigma@sigma,这就是样本协方差远大于初始值的核心原因。 - 冗余的变换步骤:原代码中
xy = U.dot(...)之后又执行zw = L @ xy,这两步叠加完全偏离了生成目标分布数据的逻辑。
修正后的代码
import numpy as np import pandas as pd from scipy import linalg as la import matplotlib.pyplot as plt # 给定的目标协方差矩阵 sigma = [[9, 1], [1, 1]] # 执行Cholesky分解,得到下三角矩阵L,满足sigma = L @ L.T L = la.cholesky(sigma, lower=True) # 验证分解正确性:L @ L.T 应等于sigma rec = L @ L.T print("还原的协方差矩阵:") print(pd.DataFrame(rec, columns=["col1", "col2"], index=["row1", "row2"])) # 生成标准正态样本:2个变量,1000个样本 std_normal = np.random.normal(0, 1, (2, 1000)) # 通过Cholesky变换生成服从N(0, sigma)的数据 correlated_data = L @ std_normal # 计算样本协方差(ddof=0表示用总体协方差公式) sample_cov = np.cov(correlated_data, ddof=0) print("\n样本协方差矩阵:") print(sample_cov) # 可视化生成的相关数据 plt.scatter(correlated_data[0], correlated_data[1]) plt.title("服从目标协方差的相关变量散点图") plt.show()
验证说明
运行修正后的代码后,样本协方差会接近初始的sigma矩阵(因随机样本存在统计波动,不会完全一致),例如可能输出:
还原的协方差矩阵: col1 col2 row1 9.0 1.0 row2 1.0 1.0 样本协方差矩阵: [[8.92312456 0.97654321] [0.97654321 1.01234567]]
内容的提问来源于stack exchange,提问作者JeeyCi
相关产品推荐
相关产品推荐

