Data Science/데이터 분석 📊

[데이터 분석] 24. SOM (Self-Organizing Map)

SLYK1D 2024. 10. 13. 09:40
728x90
반응형

1. SOM (자가 조직 지도)

이번 장에서 다루게 될 자가 조직 지도, 일명 SOM(Self-Organizing Map) 은 대뇌피질 중 시각피질의 학습과정을 모델화한 인공신경망으로 차원이 축소화된 데이터셋을 토폴로지 개념으로 효과적인 표현을 만들 수 있는 기법이다. 일반적인 신경망과 달리, 비지도학습 기법 중 하나로 주로 군집화에서 많이 사용된다. 또한 데이터의 규모가 작은 경우 K-Means 클러스터링과 유사하게 동작하지만, 데이터의 규모가 커질 수록 복잡한 데이터셋의 토폴로지를 잘 나타내는 성향이 있다.

 

2. SOM 의 구조

노드의 그리드로 구성되며, 각 노드에는 입력 데이터셋과 동일한 차원의 가중치 벡터가 포함되어있다. 각 노드에는 입력 데이터 셋과 동일한 차원의 가중치 벡터가 포함되어 있으며, 무작위로 초기화 될 수 있지만, 대략적인 근사치를 기반으로 초기화 할 경우 학습속도가 빠를 수 있다. 

 

3. SOM 알고리즘 과정

모든 가중치 벡터의 데이터 공간 상에서 유클리디언 거리를 계산해 가장 좋은 노드인 BMU(Best Machine Unit) 을 찾는다. 입력 벡터 쪽으로 일부 조정된다. 이웃 노드도 일부 조정을 하며, 이웃노드의 이동 정도는 네이버후드 함수에 의해 결정된다. 네트워크가 수렴할 때까지 샘플링을 사용해 여러 차례 반복적으로 이뤄진다. 위의 과정을 설명한 영상이 아래 있으니 참고하기 바란다. 

위의 연두섹 부분이 격자벡터를 나타내며, 영상에서 볼 수 있듯이, 랜덤으로 초기화되고 격자벡터의 업데이트 폭은 항상 일정하지 않다. 

조금 더 이해를 돕기 위해 아래 손글씨 이미지 데이터를 SOM으로 구분한 것이다. 실행하기에 앞서 SOM에 대한 별도 패키지가 필요하며, 아래 파이썬 파일을 import 해서 사용하면 된다.

som.py
0.01MB

import numpy as np

from sklearn.datasets import load_digits
from som import Som
from pylab import plot, axis, show, pcolor, colorbar, bone

digits = load_digits()
data = digits.data
labels = digits.target

# SOM 모델링
som = Som(16, 16, 64, sigma=1.0, learning_rate=0.5)
som.random_weights_init(data)

print("Initiating SOM")

som.train_random(data, 10000)
print("\nSOM Processing Complete")

bone()
pcolor(som.distance_map().T)
colorbar()
# 필요한 라이브러리 로드
if (!requireNamespace("kohonen", quietly = TRUE)) {
  install.packages("kohonen")
}
library(kohonen)

# 1. digits 데이터 로드 (유사한 데이터셋 사용)
data <- datasets::mtcars  # R에는 sklearn의 'load_digits()'와 동일한 데이터가 없으므로 대체
data <- scale(data)  # 데이터 표준화

# 2. SOM 모델링
som_grid <- somgrid(xdim = 16, ydim = 16, topo = "rectangular")
som_model <- som(data, grid = som_grid, rlen = 10000, alpha = c(0.5, 0.05), radius = 1)

print("SOM 학습 완료")

# 3. 거리 맵(distance map) 시각화
plot(som_model, type = "dist.neighbours", main = "SOM Distance Map")

# 4. 색상 맵 추가
plot(som_model, type = "property", property = som_model$distances, main = "Node Distances", palette.name = terrain.colors)

코드를 잠깐 살펴보자면, 먼저 매핑 관련 차원과 입력 데이터에 대한 차원을 입력 파라미터로 설정한다. 이 때, sigma 의 경우 가우시안 네이버후드 함수의 분포정도를 의미한다. 해당 값이 너무 작게 되면 눈금의 중심근처로 집중될 수 있다는 점에 유의해서 설정해야하고, 반대로 값이 너무 크면 그리드가 일반적으로 중심을 향해 커다란 빈 공간을 생성하는 결과가 나올 수 있다. 

다음으로 학습률(Learning Rate) 는 SOM의 초기 학습 속도를 스스로 컨트롤할 수 있는 값으로 정의한다. 구체적인 식은 다음과 같다.

$ learning\_rate(t) = \frac {learning\_rate} {(1+(t/0.5 * t))} $

위의 식에서 t는 반복횟수 인덱스를 의미한다. 이번에는 가중치를 무작위로 부여해 SOM 알고리즘을 초기화한다. 이 후 각 클래스에 대해 레이블과 색상을 지정해 SOM 알고리즘을 통해 생성된 클래스를 화면에 표출할 때, 쉽세 구분할 수 있다.

labels[labels == '0'] = 0
labels[labels == '1'] = 1
labels[labels == '2'] = 2
labels[labels == '3'] = 3
labels[labels == '4'] = 4
labels[labels == '5'] = 5
labels[labels == '6'] = 6
labels[labels == '7'] = 7
labels[labels == '8'] = 8
labels[labels == '9'] = 9

marker = ['o', 'v', '1', '3', '8', 's', 'p', 'x', 'D', '*']
colors = ["r", "g", "b", "y", "c", (0,0.1,0.8), (1, 0.5, 0), (1,1,0.3), "m", (0.4, 0.6, 0)]
for cnt, xx in enumerate(data):
    w = som.winner(xx)
    plot(w[0]+.5, w[1]+.5, marker[labels[cnt]], markerfacecolor="None", markeredgecolor=colors[labels[cnt]], markersize=12, markeredgewidth=2)
    axis([0, som.weights.shape[0], 0, som.weights.shape[1]])
    show()
# 필요한 라이브러리 로드
library(kohonen)  # SOM 모델링에 사용
library(ggplot2)  # 시각화
library(dplyr)

# SOM 모델과 데이터는 이전에 정의되었다고 가정 (som_model과 data 변수 사용)

# 1. 라벨 값 변환 (문자형 라벨을 숫자로 변환)
labels <- as.integer(as.character(labels))

# 2. 마커와 색상 설정
markers <- c("o", "v", "1", "3", "8", "s", "p", "x", "D", "*")
colors <- c("red", "green", "blue", "yellow", "cyan", 
            rgb(0, 0.1, 0.8), rgb(1, 0.5, 0), rgb(1, 1, 0.3), 
            "magenta", rgb(0.4, 0.6, 0))

# 3. SOM 위너 노드 찾기 및 시각화
plot_som <- function(data, som_model, labels, markers, colors) {
  plot(som_model, type = "mapping", bgcol = "white")
  
  for (i in 1:nrow(data)) {
    w <- som_model$unit.classif[i, ]  # 데이터 포인트의 위너 노드
    points(w[1] + 0.5, w[2] + 0.5, 
           pch = markers[labels[i] + 1],  # pch 인덱스는 1부터 시작하므로 +1
           col = colors[labels[i] + 1], 
           cex = 2, lwd = 2)
  }
}

# 4. SOM 시각화 실행
plot_som(data, som_model, labels, markers, colors)

16 x 16 노드의 SOM 시각화 결과를 보여주며, 유의 그림과 같이 각 클러스터를 토폴로지 상에 구분가능하도록 표시를 해두었다. 일부 클래스는 SOM의 공간 여러 곳에 걸쳐있는 경우도 있지만, 대다수의 클래스는 서로 다른 영역에 위치가 있다는 것을 보아, SOM 알고리즘이 상당히 효과적이라는 것을 알 수 있다.


※ 참고자료

https://ratsgo.github.io/machine%20learning/2017/05/01/SOM/

 

자기조직화지도(Self-Organizing Map) · ratsgo's blog

이번 글에서는 차원축소(dimensionality reduction)와 군집화(clustering)를 동시에 수행하는 기법인 자기조직화지도(Self-Organizing Map, SOM)를 살펴보도록 하겠습니다. 이번 글 역시 고려대 강필성 교수님 강

ratsgo.github.io

728x90
반응형