简体   繁体   English

通过透视Cholesky分解生成具有秩不足协方差的多元正态rv

[英]Generate multivariate normal r.v.'s with rank-deficient covariance via Pivoted Cholesky Factorization

I'm just beating my head against the wall trying to get a Cholesky decomposition to work in order to simulate correlated price movements. 我只是在碰壁,试图使Cholesky分解起作用,以便模拟相关的价格变动。

I use the following code: 我使用以下代码:

cormat <- as.matrix(read.csv("http://pastebin.com/raw/qGbkfiyA"))
cormat <- cormat[,2:ncol(cormat)]
rownames(cormat) <- colnames(cormat)
cormat <- apply(cormat,c(1,2),FUN = function(x) as.numeric(x))

chol(cormat)
#Error in chol.default(cormat) : 
#    the leading minor of order 8 is not positive definite

cholmat <- chol(cormat, pivot=TRUE)
#Warning message:
#    In chol.default(cormat, pivot = TRUE) :
#    the matrix is either rank-deficient or indefinite

rands <- array(rnorm(ncol(cholmat)), dim = c(10000,ncol(cholmat)))
V <- t(t(cholmat) %*% t(rands))

#Check for similarity
cor(V) - cormat  ## Not all zeros!

#Check the standard deviations
apply(V,2,sd) ## Not all ones!

I'm not really sure how to properly use the pivot = TRUE statement to generate my correlated movements. 我不太确定如何正确使用pivot = TRUE语句来生成我的相关运动。 The results look totally bogus. 结果看起来完全是假的。

Even if I have a simple matrix and I try out "pivot" then I get bogus results... 即使我有一个简单的矩阵,并且尝试“枢轴”操作,我也会得到虚假结果...

cormat <- matrix(c(1,.95,.90,.95,1,.93,.90,.93,1), ncol=3)

cholmat <- chol(cormat)
# No Error

cholmat2 <- chol(cormat, pivot=TRUE)
# No warning... pivot changes column order

rands <- array(rnorm(ncol(cholmat)), dim = c(10000,ncol(cholmat)))
V <- t(t(cholmat2) %*% t(rands))

#Check for similarity
cor(V) - cormat  ## Not all zeros!

#Check the standard deviations
apply(V,2,sd) ## Not all ones!

There are two errors with your code: 您的代码有两个错误:

  1. You did not use pivoting index to revert the pivoting done to the Cholesky factor. 您没有使用数据透视索引将数据透视还原为Cholesky因素。 Note, pivoted Cholesky factorization for a semi-positive definite matrix A is doing: 注意,半正定矩阵A枢轴Cholesky分解正在执行:

     P'AP = R'R 

    where P is a column pivoting matrix, and R is an upper triangular matrix. 其中P是列枢轴矩阵, R是上三角矩阵。 To recover A from R , we need apply the inverse of P (ie, P' ): 为了从R恢复A ,我们需要应用P的倒数(即P' ):

     A = PR'RP' = (RP')'(RP') 

    Multivariate normal with covariance matrix A , is generated by: 带有协方差矩阵A多元正态是通过以下方式生成的:

     XRP' 

    where X is multivariate normal with zero mean and identity covariance. 其中X是具有零均值和恒等协方差的多元法线。

  2. Your generation of X 您的X世代

     X <- array(rnorm(ncol(R)), dim = c(10000,ncol(R))) 

    is wrong. 是错的。 First, it should not be ncol(R) but nrow(R) , ie, the rank of X , denoted by r . 首先,它不应该是ncol(R)nrow(R)即,秩X ,记为r Second, you are recycling rnorm(ncol(R)) along columns, and the resulting matrix is not random at all. 其次,您将沿着列回收rnorm(ncol(R)) ,并且所得矩阵根本不是随机的。 Therefore, cor(X) is never close to an identity matrix. 因此, cor(X)永远不会接近单位矩阵。 The correct code is: 正确的代码是:

     X <- matrix(rnorm(10000 * r), 10000, r) 

As a model implementation of the above theory, consider your toy example: 作为上述理论的模型实现,请考虑您的玩具示例:

A <- matrix(c(1,.95,.90,.95,1,.93,.90,.93,1), ncol=3)

We compute the upper triangular factor (suppressing possible rank-deficient warnings) and extract inverse pivoting index and rank: 我们计算较高的三角因子(抑制可能的等级不足警告),并提取反向枢轴索引和等级:

R <- suppressWarnings(chol(A, pivot = TRUE))
piv <- order(attr(R, "pivot"))  ## reverse pivoting index
r <- attr(R, "rank")  ## numerical rank

Then we generate X . 然后我们生成X For better result we centre X so that column means are 0. 为了获得更好的结果,我们将X居中,以使列均值为0。

X <- matrix(rnorm(10000 * r), 10000, r)
## for best effect, we centre `X`
X <- sweep(X, 2L, colMeans(X), "-")

Then we generate target multivariate normal: 然后我们生成目标多元正态:

## compute `V = RP'`
V <- R[1:r, piv]

## compute `Y = X %*% V`
Y <- X %*% V

We can verify that Y has target covariance A : 我们可以验证Y具有目标协方差A

cor(Y)
#          [,1]      [,2]      [,3]
#[1,] 1.0000000 0.9509181 0.9009645
#[2,] 0.9509181 1.0000000 0.9299037
#[3,] 0.9009645 0.9299037 1.0000000

A
#     [,1] [,2] [,3]
#[1,] 1.00 0.95 0.90
#[2,] 0.95 1.00 0.93
#[3,] 0.90 0.93 1.00

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何处理 R 中的“秩亏拟合可能具有误导性”? - How to deal with “ rank-deficient fit may be misleading” in R? compar.gee 模型“秩亏模型矩阵”错误 - compar.gee model 'rank-deficient model matrix' error 我可以使用Cholesky分解生成具有相关性1的双变量正态随机变量吗? - Can I generate bivariate normal random variables with correlation 1 using Cholesky factorization? 循环中的 predict.lm()。 警告:来自秩亏拟合的预测可能会产生误导 - predict.lm() in a loop. warning: prediction from a rank-deficient fit may be misleading 系数表中没有不符合秩的NA行; 如何插入? - Coefficient table does not have NA rows in rank-deficient fit; how to insert them? 如何在我的线性模型上解决“秩不足拟合可能会误导错误”的问题? - How to solve “rank-deficient fit may be misleading error” on my linear model? 如何在 R 中生成多元正态数据? - How to generate multivariate normal data in R? 通过QR分解,SVD(和Cholesky分解?)计算投影/帽子矩阵 - Compute projection / hat matrix via QR factorization, SVD (and Cholesky factorization?) 在R中创建一个新的概率分布(依赖于之前的r.v.) - Create a new probability distribution (relying on the previous r.v.) in R R中的多元偏态正态 - multivariate skew normal in R
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM