표본의 표본 공분산 행렬 를 추정하고 대칭 행렬을 얻습니다. 로 , I 만들고 싶습니다 -variate 정상 분산 RN을하지만, 그러므로 나는의 콜레 분해 필요가 . 가 양의 양수가 아닌 경우 어떻게해야 합니까?C n C C
표본의 표본 공분산 행렬 를 추정하고 대칭 행렬을 얻습니다. 로 , I 만들고 싶습니다 -variate 정상 분산 RN을하지만, 그러므로 나는의 콜레 분해 필요가 . 가 양의 양수가 아닌 경우 어떻게해야 합니까?C n C C
답변:
문제는 단일 공분산 행렬 를 사용하여 다변량 정규 분포에서 랜덤 변량을 생성하는 방법에 관한 것 입니다. 이 답변은 모든 공분산 행렬에서 작동하는 한 가지 방법을 설명합니다 . 정확성을 테스트 하는 구현을 제공합니다 .R
때문에 공분산 행렬이며, 반드시 대칭 포지티브 semidefinite이다. 배경 정보를 완성하려면 를 원하는 평균의 벡터로 설정하십시오. μ
때문에 대칭, 그 특이 값 분해 (SVD)과 eigendecomposition 자동으로 양식을해야합니다
일부 직교 행렬 및 대각선 행렬 . 일반적으로 의 대각선 요소 는 음이 아닙니다 (모두 진짜 제곱근을 가짐을 의미합니다 : 대각선 행렬 을 형성 할 양의 것을 선택하십시오 ). 에 대한 정보에 따르면 이러한 대각선 요소 중 하나 이상은 0이지만 후속 작업에는 영향을 미치지 않으며 SVD 계산을 방해하지 않습니다.D 2 D 2 D C
하자 표준 다변량 정규 분포가 각 구성 요소는 제로 평균, 단위 분산을 가지고 있으며, 모든 공분산은 제로이다 : 그것의 공분산 행렬은 정체성이다 . 그러면 랜덤 변수 는 공분산 행렬을가집니다I Y = V D X
결과적으로 랜덤 변수 는 평균 및 공분산 행렬 을 갖는 다변량 정규 분포를 갖습니다 .
다음 R
코드는 주어진 차원과 순위의 공분산 행렬을 생성하고 SVD로 분석하거나 주석 처리 된 코드에서 고유 분해로 분석하고 해당 분석을 사용하여 의 지정된 수의 실현을 생성합니다 (평균 벡터 ) 그런 다음 해당 데이터의 공분산 행렬을 원하는 공분산 행렬과 숫자 및 그래픽으로 비교합니다. 도시 된 바와 같이, 의 차원 이 이고 의 순위 가 경우 실현을 생성 합니다 . 출력은
rank L2
5.000000e+01 8.846689e-05
즉, 데이터의 순위도 이고 데이터에서 추정 한 공분산 행렬 은 10s 거리 내에 있습니다 . 보다 자세한 검사로서, 계수 는 추정 계수와 비교하여 표시됩니다. 그들은 모두 평등 선에 가깝습니다.
이 코드는 이전 분석과 정확히 일치하므로 설명이 필요하지 않습니다 ( R
사용자가 선호하는 응용 프로그램 환경에서 코드를 에뮬레이션 할 수있는 사용자 도 마찬가지 임). 부동 소수점 알고리즘을 사용할 때주의해야 할 점이 있습니다. 의 항목은 부정확성으로 인해 쉽게 부정적이지만 작을 수 있습니다. 자체 를 찾으려면 제곱근을 계산하기 전에 이러한 항목을 제로화해야 합니다.
n <- 100 # Dimension
rank <- 50
n.values <- 1e4 # Number of random vectors to generate
set.seed(17)
#
# Create an indefinite covariance matrix.
#
r <- min(rank, n)+1
X <- matrix(rnorm(r*n), r)
C <- cov(X)
#
# Analyze C preparatory to generating random values.
# `zapsmall` removes zeros that, due to floating point imprecision, might
# have been rendered as tiny negative values.
#
s <- svd(C)
V <- s$v
D <- sqrt(zapsmall(diag(s$d)))
# s <- eigen(C)
# V <- s$vectors
# D <- sqrt(zapsmall(diag(s$values)))
#
# Generate random values.
#
X <- (V %*% D) %*% matrix(rnorm(n*n.values), n)
#
# Verify their covariance has the desired rank and is close to `C`.
#
s <- svd(Sigma <- cov(t(X)))
(c(rank=sum(zapsmall(s$d) > 0), L2=sqrt(mean(Sigma - C)^2)))
plot(as.vector(C), as.vector(Sigma), col="#00000040",
xlab="Intended Covariances",
ylab="Estimated Covariances")
abline(c(0,1), col="Gray")
해결책 방법 A :
MATLAB에서 코드는
D = 0.5 * (C + C');
D = D + (m - min(eig(CD)) * eye(size(D));
해결 방법 B : 볼록한 SDP (반 미정 프로그램)를 공식화하고 풀고 차이의 최소 기준에 따라 C에서 가장 가까운 행렬 D를 찾아 최소 고유 값 m을 지정하여 D가 양의 유한 값을 갖도록합니다.
MATLAB에서 CVX를 사용하면 코드는 다음과 같습니다.
n = size(C,1);
cvx_begin
variable D(n,n)
minimize(norm(D-C,'fro'))
D -m *eye(n) == semidefinite(n)
cvx_end
솔루션 방법 비교 : 초기 행렬을 대칭 화하는 것 외에도 솔루션 방법 A는 대각선 요소 만 공통 양만큼 조정 (증가)하고 대각선 이외의 요소는 변경하지 않습니다. 솔루션 방법 B는 양의 한정 행렬 D와 원래의 행렬 C의 차이의 최소 frobenius 규범의 의미에서 지정된 최소 고유 값을 갖는 가장 가까운 (원본 행렬에 대한) 양의 유한 행렬을 찾습니다. 비 대각선 요소를 포함하도록 D-C의 모든 요소의 제곱 차이. 따라서 대각선 이외의 요소를 조정함으로써 대각선 요소를 증가시킬 필요가있는 양을 줄일 수 있으며, 대각선 요소가 반드시 같은 양만큼 증가 할 필요는 없습니다.
나는 당신이 추정하는 모델에 대해 생각하면서 시작할 것입니다.
공분산 행렬이 양의 반 정밀도가 아닌 경우 변수에 공선 성 문제가 있음을 나타낼 수 있으며 이는 모형에 문제가 있음을 나타내며 반드시 숫자 방법으로 해결하지 않아야합니다.
행렬이 숫자로 인해 양의 반정 수가 아닌 경우 여기에서 읽을 수있는 몇 가지 해결책이 있습니다.
한 가지 방법은 고유 값 분해에서 행렬을 계산하는 것입니다. 이제 이러한 프로세스의 배후에있는 수학을 너무 많이 알지 못하지만 연구 결과에서이 도움말 파일을 보는 것이 유익한 것으로 보입니다.
http://stat.ethz.ch/R-manual/R-patched/library/Matrix/html/chol.html
R의 다른 관련 명령
또한 Matrix 패키지에서 'nearPD'를 확인하십시오.
더 이상 도움을 드릴 수 없었지만 검색을 통해 올바른 방향으로 나아가는 데 도움이되기를 바랍니다.
R에있는 Matrix 패키지의 nearPD 함수에서 결과를 얻을 수 있습니다. 그러면 실제 가치가있는 행렬이 다시 나타납니다.
library(Matrix)
A <- matrix(1, 3,3); A[1,3] <- A[3,1] <- 0
n.A <- nearPD(A, corr=T, do2eigen=FALSE)
n.A$mat
# 3 x 3 Matrix of class "dpoMatrix"
# [,1] [,2] [,3]
# [1,] 1.0000000 0.7606899 0.1572981
# [2,] 0.7606899 1.0000000 0.7606899
# [3,] 0.1572981 0.7606899 1.0000000