2022. 10. 17. 11:16ㆍR study/Multivariate Analysis
이 글은 책 'R 응용 다변량 분석(나종화)'를 바탕으로 작성되었습니다.
특잇값분해(singuar value decomposition, SVD)는 고윳값분해와 마찬가지로 행렬을 대각화하는 방법이다. 고윳값분해가 정사각($n\times n$)행렬에 대해서만 적용되는 반면, 특잇값분해는 직사각($m\times n$)행렬에 대해서도 적용되므로 그 활용도가 매우 높다. 다변량 분석(주성분 분석, 다차원척도법 등), 데이터마이닝과 기계학습 등의 주요 알고리즘에 대해 특잇값분해가 사용된다.
$$ A=U\Sigma V^{T} $$
$A$ : 임의의 $m\times n$ 행렬
$U$ : $m\times n$ 직교행렬(Orthgonal matrix)
$V$ : $n\times n$ 직교행렬
$\Sigma $ : $m\times n$ 직사각 대각행렬
특잇값분해의 개념은 건너 뛰고 SVD의 기하학적 의미 설명
행렬 $A$를 통한 선형변환($Ax$)는 벡터(x)에 대해 회전(rotation), 스케일 변환, 반사(reflection)의 작용을 한다. 이 과정은 직교행렬($V^{T}$)에 의해 회전되고, 대각행렬($\Sigma$)에 의해 스케일 변환된 후, 다시 직교행렬($U$)에 의해 회전되는 과정의 결과와 동일하다. 직교행렬은 회전변환 또는 반사 회전변환(180도)을 수행하고, 대각행렬은 각 좌표성분으로의 스케일 변환을 수행한다.
SVD가 활용되는 예로는 데이터 축소, 선형 최소제곱해 문제, 영상처리 및 압축, 잡음제거, 데이터 군집화에서 군집개수 결정, 다변량 이상치 탐지, 관측값 변수의 추세 탐지, 행렬의 계수 결정 등이 있다.
library(OpenImageR)
img <- readImage("C:/Users/82109/OneDrive/사진/vegtable.png")
dim(img)
imageShow(img)
사진 출처 : RGB 이미지나 컬러맵을 회색조로 변환하기 - MATLAB rgb2gray - MathWorks 한국
가로 pixel이 467, 세로 pixel이 678, color channel이 3개
r <- rgb_2gray(img)
imageShow(r)
dim(r)
grey로 변경
r[1:10, 1:10]
r[100:130,100:130]
summary(r)
pixel의 summary
r.svd = svd(r)
u = r.svd$u
d = r.svd$d
v = r.svd$v
dim(u)
dim(v)
dim(v)
length(d)
d
round(d, 3)
SVD 적용
plot(1:length(r.svd$d), r.svd$d)
y축은 특잇값의 크기이다. singular value가 점점 떨어지는 것을 볼 수 있다.
u1 <- as.matrix(u[,1]) # 467x1
v1 <- as.matrix(v[,1]) # 678x1
d1 <- as.matrix(d[1,1]) # scalar
l1 <- u1%*%d1%*%t(v1) # 467x678
plot(0, type='n', axes=F, xlab="", ylab="")
imageShow(l1)
depth <- 5
us <- as.matrix(u[,1:depth])
vs <- as.matrix(v[,1:depth])
ds <- as.matrix(d[1:depth, 1:depth])
ls <- us%*%ds%*%t(vs)
plot(0, type='n', axes=F, xlab="", ylab="")
imageShow(ls)
depth <- 20
us <- as.matrix(u[,1:depth])
vs <- as.matrix(v[,1:depth])
ds <- as.matrix(d[1:depth, 1:depth])
ls <- us%*%ds%*%t(vs)
plot(0, type='n', axes=F, xlab="", ylab="")
imageShow(ls)
SVD를 근사했을 때 1개의 특잇값을 이용했을 때부터 20개의 특잇값을 근사했을 때 이다.
특잇값이 커질 수록 사진이 점점 선명해지는 것을 볼 수 있고 정보의 손실이 적어진다.
원본 이미지의 경우 $400\times 678=271200$ 메모리가 필요한 반면, $k=20$인 SVD 사용 시 25580($467\times 20(U)+20(\Sigma )+20\times 678=25580$) 메모리가 필요하다. 원본의 약 10% 메모리로 이미지 압축했다.
$k=150$일 경우 실제 이미지와 화질이 비슷하였다.
이 그림을 컬러 이미지로도 근사하였다.
depth <- 30
x <- readImage("C:/Users/82109/OneDrive/사진/vegtable.png")
for(i in 1:3){
x.svd <- svd(x[,,i])
d <- diag(x.svd$d)
u <- x.svd$u
v <- x.svd$v
us <- as.matrix(u[, 1:depth])
vs <- as.matrix(v[, 1:depth])
ds <- as.matrix(d[1:depth, 1:depth])
assign(paste("ls", i, sep = ""), us%*%ds%*%t(vs))
}
ls <- array(c(ls1, ls2, ls3), c(nrow(ls1), ncol(ls1),3))
plot(0, type="n", axes=F, xlab="", ylab="")
imageShow(ls)
'R study > Multivariate Analysis' 카테고리의 다른 글
| 결측값 대치 (1) | 2022.10.03 |
|---|