我正在尝试使用SVD分解来计算协方差矩阵,但它无法正常工作。 我已经构建了以下功能。
任何人都可以帮我指出我犯过的错误。
提前致谢
svdcov = function(x){
svdmat = svd(x)
## d is the singular values sometimes denoted as s
## u is left singular
## v is right singular
dvec = matrix(data=NA,nrow=length(x),ncol=1)
dvec[,1] = svdmat$d
covmat = t(t(svdmat$v%*%dvec)%*%t(svdmat$u)%*%svdmat$u)%*%t(dvec)%*%svdmat$v
colnames(covmat) = colnames(x)
rownames(covmat) = colnames(x)
return(covmat)
}
答案 0 :(得分:3)
奇异值分解为X=UDV'
。
如果你想计算X'X
,
这将是(UDV')'(UDV')
,即
VDU'UDV'
,即V D^2 V'
(U
是正交且D
对角线)。
f <- function(x) {
s <- svd(x)
v <- s$v
d <- diag(s$d) # It is a vector: transform it to a diagonal matrix
v %*% d^2 %*% t(v)
}
x <- matrix( rnorm(200), nc=4 )
stopifnot( all( abs( f(x) - t(x) %*% x ) < 1e-12 ) )
要获得方差矩阵,您仍需要减去所有列的平均值, 并除以观察数量。
stopifnot( all( abs(
var(x) -
f(scale(x, scale=FALSE)) / (nrow(x)-1)
) < 1e-12
) )