사례 연구: 이미지 데이터의 시각화 :: 차원 축소 - mindscale
Skip to content

사례 연구: 이미지 데이터의 시각화

데이터 다운 링크

  • 목적: 손글씨 이미지 파일을 2차원에 시각화하기
  • 8 X 8 사이즈의 이미지 파일, 즉 64차원
  • 밝기: 1~16

패키지 설치

install.packages(c('lle', 'tsne', 'vegan'))

데이터 파일 불러오기

data = read.csv('digit.csv')

데이터 정보

dim(data)
[1] 1797   65
  • 1797개의 손글씨 이미지
  • 65개의 종: 64개의 점의 밝기 + 손글씨 숫자가 무슨 숫자인지에 대한 정보

첫 번째 손글씨의 정보

data[1,1:8]
  V1 V2 V3 V4 V5 V6 V7 V8
1 0  0  5  13 9  1  0  0 
data[1,9:16]
  V9 V10 V11 V12 V13 V14 V15 V16
1 0  0   13  15  10  15  5   0  
data[1,17:24]
  V17 V18 V19 V20 V21 V22 V23 V24
1 0   3   15  2   0   11  8   0  
data[1,25:32]
  V25 V26 V27 V28 V29 V30 V31 V32
1 0   4   12  0   0   8   8   0  

시각화를 위한 사전 작업

image = data[1:64]
number = as.character(data[,65])
color = rainbow(10)[data[,65]+1]
  • image: 이미지에 해당하는 부분
  • number: 숫자 정보에 해당하는 부분
  • number는 후에 텍스트 형태로 출력을 하기 위해 문자 형태로 변환함
  • color: 숫자 별로 색을 지정

PCA

pca = prcomp(image)
plot(pca$x, typ = 'n')
text(pca$x, number, col = color)
  • 64차원의 이미지를 2차원으로 축소
  • 비슷한 숫자들끼리 비슷한 위치에 있음
  • 5, 7, 8이 잘 구분이 안되어 있음
  • 비선형적인 패턴을 많이 가진 부분은 잘 표현되지 못함

MDS

d = dist(image)
mds = cmdscale(d)
plot(mds, typ = 'n')
text(mds, number, col = color)
  • 5, 7, 8이 잘 구분이 안되어 있음

IsoMap

library(vegan)
iso = isomap(d, ndim = 2, k = 30)
plot(iso$points, typ = 'n')
text(iso$points, number, col = color)
Loading required package: permute
Loading required package: lattice
This is vegan 2.5-6
  • 앞에서 했던 것보다 숫자들끼리 덜 겹쳐짐
  • 원래 공간에 복잡하게 접혀져 있는 것들을 잘 펼쳐서 표현
  • IsoMap은 거리만을 이용하니까 이번 사례에서는 LLE보다 잘 나옴

LLE

library(lle)
lin = lle(image, 2, 30)
plot(lin$Y, typ = 'n')
text(lin$Y, number, col = color)
Loading required package: scatterplot3d
Loading required package: MASS
Loading required package: snowfall
Loading required package: snow
finding neighbours
calculating weights
computing coordinates
  • 결과가 좋지 않음
  • LLE는 평면이 있을 것이라고 가정을 하는데 이 데이터에는 평면이 없어 이런 결과를 도출한 듯함

tsne

library(tsne)
ts = tsne(image, initial_dims = 64)
plot(ts, typ = 'n')
text(ts, number, col = color)
sigma summary: Min. : 0.221408575610339 |1st Qu. : 0.620063784622015 |Median : 0.675069430571825 |Mean : 0.687671788667607 |3rd Qu. : 0.739130003054694 |Max. : 1.52805698437237 |
Epoch: Iteration #100 error is: 19.217536943355
Epoch: Iteration #200 error is: 1.3587223315932
Epoch: Iteration #300 error is: 1.14080852254214
Epoch: Iteration #400 error is: 1.04440997888217
Epoch: Iteration #500 error is: 1.00637787550838
Epoch: Iteration #600 error is: 0.986854976155903
Epoch: Iteration #700 error is: 0.975567595309222
Epoch: Iteration #800 error is: 0.968378888065802
Epoch: Iteration #900 error is: 0.963365469441065
Epoch: Iteration #1000 error is: 0.959970056385717
  • 숫자별로 구분이 잘 되었음
  • 겹치는 숫자도 거의 없음
  • 부분적인 구조를 잘 보존했기 때문에 이런 결과가 나옴
  • 전체적인 구조를 잘 보존하지 못한다는 단점이 이 사례에서는 장점이 되었음