我想绘制样品。维基百科建议任一使用的Cholesky或特征分解,即 或
因此,样品可通过得出: 或 其中
维基百科建议它们在生成样本方面都同样出色,但是Cholesky方法具有更快的计算时间。这是真的?尤其是在使用蒙特卡洛方法时,在数值上,沿对角线的方差可能相差几个数量级?是否有对此问题的正式分析?
car::ellipse
)上获取椭圆的顶点。尽管在不同的应用程序中提出了问题,但背后的理论是相同的。您会在那里看到漂亮的图形进行几何解释。
我想绘制样品。维基百科建议任一使用的Cholesky或特征分解,即 或
因此,样品可通过得出: 或 其中
维基百科建议它们在生成样本方面都同样出色,但是Cholesky方法具有更快的计算时间。这是真的?尤其是在使用蒙特卡洛方法时,在数值上,沿对角线的方差可能相差几个数量级?是否有对此问题的正式分析?
car::ellipse
)上获取椭圆的顶点。尽管在不同的应用程序中提出了问题,但背后的理论是相同的。您会在那里看到漂亮的图形进行几何解释。
Answers:
Straka等人针对无味卡尔曼滤波器研究了该问题,该算法从多元正态分布中提取(确定性)样本作为算法的一部分。幸运的是,该结果可能适用于蒙特卡洛问题。
Cholesky分解(CD)和Eigen分解(ED)-因此,实际的矩阵平方根(MSR)都是可以分解正半定矩阵(PSD)的所有方式。
考虑SVD一个PSD矩阵,。由于P是PSD,因此实际上与具有P = U S U T的ED相同。:此外,我们可以通过其平方根拆分对角矩阵P = û √,指出√。
现在我们可以引入一个任意正交矩阵:
。
的选择实际上会影响估计性能,尤其是在协方差矩阵中存在较强的非对角线元素时。
本文研究了三个选择:
经过大量分析(引用),从中得出以下结论:
对于具有不相关元素的待转换随机变量,所有三个考虑的MD都提供相同的sigma点,因此,它们对[Unscented Transform]近似的质量几乎没有影响。在这种情况下,CD可能因其低成本而成为首选。
如果随机变量包含相关元素,则使用不同的[分解]可能会严重影响已转换随机变量的均值或协方差矩阵的[无味变换]近似值的质量。以上两种情况表明,[ED]应该是首选。
如果要转换的变量的元素表现出很强的相关性,使得相应的协方差矩阵几乎是奇异的,则必须考虑另一个问题,即计算MD的算法的数值稳定性。对于奇异协方差矩阵,SVD在数值上比ChD稳定得多。
参考:
这是使用R比较两种方法的计算时间的简单说明。
library(mvtnorm)
library(clusterGeneration)
set.seed(1234)
mean <- rnorm(1000, 0, 1)
sigma <- genPositiveDefMat(1000)
sigma <- sigma$Sigma
eigen.time <- system.time(
rmvnorm(n=1000, mean=mean, sigma = sigma, method = "eigen")
)
chol.time <- system.time(
rmvnorm(n=1000, mean=mean, sigma = sigma, method = "chol")
)
运行时间是
> eigen.time
user system elapsed
5.16 0.06 5.33
> chol.time
user system elapsed
1.74 0.15 1.90
将样本量增加到10000时,运行时间为
> eigen.time <- system.time(
+ rmvnorm(n=10000, mean=mean, sigma = sigma, method = "eigen")
+ )
>
> chol.time <- system.time(
+ rmvnorm(n=10000, mean=mean, sigma = sigma, method = "chol")
+ )
> eigen.time
user system elapsed
15.74 0.28 16.19
> chol.time
user system elapsed
11.61 0.19 11.89
希望这可以帮助。
这是手册或穷人的自我证明:
> set.seed(0)
> # The correlation matrix
> corr_matrix = matrix(cbind(1, .80, .2, .80, 1, .7, .2, .7, 1), nrow=3)
> nvar = 3 # Three columns of correlated data points
> nobs = 1e6 # One million observations for each column
> std_norm = matrix(rnorm(nvar * nobs),nrow=nobs, ncol=nvar) # N(0,1)
1. SVD METHOD:
> ptm <- proc.time()
> # Singular Value Decomposition method:
> svd = svd(corr_matrix)
> rand_data_svd = t(svd$u %*% (diag(3) * sqrt(svd$d)) %*% t(std_norm))
> proc.time() - ptm
user system elapsed
0.29 0.05 0.34
>
> ptm <- proc.time()
2. CHOLESKY METHOD:
> # Cholesky method:
> chole = t(chol(corr_matrix))
> rand_data_chole = t(chole %*% t(std_norm))
> proc.time() - ptm
user system elapsed
0.25 0.03 0.31
Thank you to @userr11852 for pointing out to me that there is a better way to calculate the difference in performance between SVD and Cholesky, in favor of the latter, using the function microbenchmark
. At his suggestion, here is the result:
microbenchmark(chol(corr_matrix), svd(corr_matrix))
Unit: microseconds
expr min lq mean median uq max neval cld
chol(corr_matrix) 24.104 25.05 28.74036 25.995 26.467 95.469 100 a
svd(corr_matrix) 108.701 110.12 116.27794 111.065 112.719 223.074 100 b
microbenchmark
and it really makes a difference.