내용

글번호 795
작성자 허진경
작성일 2018-01-18 09:12:58
제목 R을 이용한 특이값 분해, Singular Value Decomposition (SVD)
내용 코드와 결과
> rm(list=ls())
> # 다음 데이터 A를 특이값 분해 하세요.
> # 설명참고 http://web.mit.edu/be.400/www/SVD/Singular_Value_Decomposition.htm
> # A = U %*% S  %*% t(V)
> 
> (A <- matrix( c(2,1,0,0,4,3,0,0), ncol=2)) # 데이터
     [,1] [,2]
[1,]    2    4
[2,]    1    3
[3,]    0    0
[4,]    0    0
> 
> # 특이값과 U를 구하기 위해 A와 A의 전치행렬을 곱합니다.
> 
> (AAT <- A %*% t(A)) 
     [,1] [,2] [,3] [,4]
[1,]   20   14    0    0
[2,]   14   10    0    0
[3,]    0    0    0    0
[4,]    0    0    0    0
> 
> # R의 eigen() 함수는 고유값과 고유값 행렬을 구해줍니다.
> ev <- eigen(AAT)$values #29.8660687  0.1339313  0.0000000  0.0000000
> # 고유값은 AAT - lambdaI = 0 을 이용해서도 구할 수 있습니다.
> 
> # 특이값은 고유값에 루트를 씌워야 합니다.
> (ev_sqrt <- sqrt(ev)) # 5.47, 0.37
[1] 5.4649857 0.3659662 0.0000000 0.0000000
> 
> # 특이값을 이용해 Sigma 행렬을 만들어줍니다.
> (S <- diag(ev_sqrt))
         [,1]      [,2] [,3] [,4]
[1,] 5.464986 0.0000000    0    0
[2,] 0.000000 0.3659662    0    0
[3,] 0.000000 0.0000000    0    0
[4,] 0.000000 0.0000000    0    0
> (S <- S[,-c(3,4)])
         [,1]      [,2]
[1,] 5.464986 0.0000000
[2,] 0.000000 0.3659662
[3,] 0.000000 0.0000000
[4,] 0.000000 0.0000000
> 
> # U는 AAT를 고유값 분해한 고유벡터입니다. 
> # 이것은 (ATA - 고유값중하나 * I)x = 0 식을 이용해 구할 수 있습니다.
> (U <- eigen(AAT)$vectors)
          [,1]       [,2] [,3] [,4]
[1,] 0.8174156 -0.5760484    0    0
[2,] 0.5760484  0.8174156    0    0
[3,] 0.0000000  0.0000000    0    1
[4,] 0.0000000  0.0000000    1    0
> 
> # V를 구하기 위해 A의 전치행렬과 A행렬을 곱합니다.
> ATA <- t(A) %*% A
> eigen(ATA)$values #AAT를 이용해 구한 교유값과 동일한 값을 출력합니다.
[1] 29.8660687  0.1339313
> 
> # ATA의 교유벡터를 얻습니다.
> V <- eigen(ATA)$vectors
> V
          [,1]       [,2]
[1,] 0.4045536 -0.9145143
[2,] 0.9145143  0.4045536
> 
> # 이제 U, S, V를 얻었으니 증명을 해야 합니다.
> # VT는 V의 전치행렬이며, AT는 A의 전치행렬, UT는 U의 전치행렬 입니다.
> #A=USVT and AT=VSUT
> #ATA = VSUTUSVT
> #ATA = VS2VT
> #ATAV = VS2
코드
rm(list=ls())
# 다음 데이터 A를 특이값 분해 하세요.
# 설명참고 http://web.mit.edu/be.400/www/SVD/Singular_Value_Decomposition.htm
# A = U %*% S  %*% t(V)

(A <- matrix( c(2,1,0,0,4,3,0,0), ncol=2)) # 데이터

# 특이값과 U를 구하기 위해 A와 A의 전치행렬을 곱합니다.

(AAT <- A %*% t(A)) 

# R의 eigen() 함수는 고유값과 고유값 행렬을 구해줍니다.
ev <- eigen(AAT)$values #29.8660687  0.1339313  0.0000000  0.0000000
# 고유값은 AAT - lambdaI = 0 을 이용해서도 구할 수 있습니다.

# 특이값은 고유값에 루트를 씌워야 합니다.
(ev_sqrt <- sqrt(ev)) # 5.47, 0.37

# 특이값을 이용해 Sigma 행렬을 만들어줍니다.
(S <- diag(ev_sqrt))
(S <- S[,-c(3,4)])

# U는 AAT를 고유값 분해한 고유벡터입니다. 
# 이것은 (ATA - 고유값중하나 * I)x = 0 식을 이용해 구할 수 있습니다.
(U <- eigen(AAT)$vectors)

# V를 구하기 위해 A의 전치행렬과 A행렬을 곱합니다.
ATA <- t(A) %*% A
eigen(ATA)$values #AAT를 이용해 구한 교유값과 동일한 값을 출력합니다.

# ATA의 교유벡터를 얻습니다.
V <- eigen(ATA)$vectors
V

# 이제 U, S, V를 얻었으니 증명을 해야 합니다.
# VT는 V의 전치행렬이며, AT는 A의 전치행렬, UT는 U의 전치행렬 입니다.
#A=USVT and AT=VSUT
#ATA = VSUTUSVT
#ATA = VS2VT
#ATAV = VS2