자기 조직화 지도: 파이썬 예제가 포함된 직관적인 가이드

자기 조직화 지도(SOM)는 비지도 학습 작업에 사용되는 일종의 인공 신경망으로, 클러스터링과 같은 작업을 수행합니다. 데이터 포인트 집합을 주면, 모델은 데이터를 클러스터로 나누는 법을 학습합니다. SOM은 복잡한 다차원 데이터를 더 낮은 차원(일반적으로 2차원) 그리드로 투영합니다. 이는 시각화를 더 쉽게 합니다. 따라서 SOM은 고차원 데이터를 시각화하는 데에도 사용됩니다.

이번 튜토리얼에서는 SOM의 핵심 개념, 학습 과정 및 일반적인 사용 사례를 탐구합니다. 우리는 MiniSom 라이브러리를 사용하여 Python에서 SOM을 구현하는 방법과 결과를 시각적으로 표현하는 방법을 설명합니다. 마지막으로, SOM 모델 학습에서 중요한 하이퍼파라미터와 이를 미세 조정하는 방법에 대해 논의합니다.

자기 조직화 지도(SOM) 이해하기

이 섹션에서는 SOM의 핵심 개념, 학습 과정 및 사용 사례를 소개합니다.

핵심 개념

자기 조직화 맵(SOM)은 이해하는 데 중요한 개념 세트를 포함합니다.

뉴런

SOM은 본질적으로 뉴런의 그리드입니다. 학습 중, 입력 데이터 포인트와 가장 가까운 가중치 벡터를 가진 뉴런이 자신의 가중치와 이웃 뉴런의 가중치를 입력 데이터 포인트와 더욱 일치하도록 조정합니다. 여러 번의 반복을 통해 이웃 뉴런 그룹이 관련 데이터 포인트에 매핑됩니다. 이로 인해 입력 데이터 세트의 클러스터링이 발생합니다.

그리드 구조

SOM의 뉴런은 그리드 형태로 구성되어 있습니다. 인접한 뉴런은 유사한 데이터 포인트에 매핑됩니다. 더 큰 데이터셋은 더 큰 그리드가 필요합니다. 일반적으로 이 그리드는 2차원입니다. 그리드 구조는 고차원 데이터가 매핑되는 저차원 공간 역할을 합니다. 그리드는 데이터 패턴과 클러스터를 시각화하는 데 도움을 줍니다.

데이터 포인트 매핑

각 데이터 포인트는 거리 메트릭을 사용하여 모든 뉴런과 비교됩니다. 입력 데이터 포인트에 가장 가까운 가중치 벡터를 가진 뉴런이 해당 데이터 포인트의 최고 일치 유닛 (BMU)입니다.

BMU가 식별되면, BMU와 그 이웃 뉴런의 가중치가 업데이트됩니다. 이 업데이트는 BMU와 이웃 뉴런을 입력 데이터 포인트에 더 가깝게 만듭니다. 이 매핑은 데이터의 위상을 보존하여 유사한 데이터 포인트가 근처 뉴런에 매핑되도록 합니다.

자기조직화 지도(SOM)의 학습 과정

SOM 훈련은 비지도 학습으로 간주됩니다. 이는 레이블이 있는 데이터 세트를 기반으로 하지 않기 때문입니다. SOM을 훈련하는 목표는 유사한 데이터 포인트가 인접한 뉴런에 매핑되도록 뉴런의 가중치 벡터를 반복적으로 조정하는 것입니다.

경쟁 학습

SOM은 경쟁 학습을 사용합니다 (경량 하강 및 역전파 대신). 뉴런은 각 입력 데이터 포인트에 대한 최적 일치 유닛 (BMU)가 되기 위해 경쟁합니다. 데이터 포인트와 가장 가까운 뉴런이 BMU로 결정됩니다. BMU와 그 이웃 뉴런은 데이터 포인트와의 거리를 더 줄이기 위해 업데이트됩니다. 이웃 뉴런은 관련 데이터 포인트에 매핑됩니다. 이는 뉴런 간의 전문화 및 입력 데이터 포인트의 클러스터링으로 이어집니다. 

거리 함수 

SOM은 뉴런과 데이터 포인트 간의 거리를 측정하기 위해 거리 함수를 사용합니다. 이 거리는 각 데이터 포인트의 BMU를 결정하는 데 사용됩니다. MiniSom은 선택할 수 있는 네 가지 거리 함수가 있습니다: 

이웃 함수

데이터 포인트의 BMU를 식별한 후, BMU와 그 이웃 뉴런은 해당 데이터 포인트의 방향으로 업데이트됩니다. 이웃 함수는 SOM이 입력 데이터의 위상적 관계를 유지하도록 보장합니다. 이웃 함수는 다음을 결정합니다:

  • 어떤 뉴런이 BMU의 이웃으로 간주되는지
  • 이웃 뉴런이 업데이트되는 정도. 일반적으로, BMU에 가까운 뉴런은 멀리 있는 뉴런보다 더 큰 조정을 받습니다.

MiniSom은 세 가지 이웃 함수를 제공합니다:

  • 가우시안(기본값).
  • 버블
  • 멕시코 모자
  • 삼각형

반복 과정

SOM에서의 학습 과정은 여러 번의 반복을 통해 이루어집니다. 각 반복에서 SOM은 많은 입력 데이터 포인트를 처리합니다. 우리는 다음 단계에서 학습 과정을 개략적으로 설명합니다:

  • 훈련이 시작되면 모든 뉴런의 가중치는 (무작위로) 초기화됩니다.
  • 입력 데이터 포인트가 주어지면 각 뉴런은 입력으로부터의 거리를 계산합니다.
    • 가장 작은 거리를 가진 뉴런이 BMU로 선언됩니다.
  • BMU와 그 이웃들의 가중치는 입력 벡터에 더 가까워지도록 조정됩니다. 이 조정의 정도는 다음에 의해 결정됩니다:
    • 이웃 함수: BMU에서 멀리 떨어진 뉴런은 BMU에 가까운 뉴런보다 덜 업데이트됩니다. 이는 데이터의 위상 구조를 유지합니다.
    • 학습률: 더 높은 학습률은 더 큰 업데이트로 이어집니다.

이 단계는 많은 반복을 통해 여러 입력 데이터 포인트를 거치면서 반복됩니다. 가중치는 점진적으로 업데이트되어 맵이 자가 조직화되고 데이터 구조를 포착합니다.

학습률과 이웃 반경은 일반적으로 시간이 지남에 따라 감소하여 SOM이 가중치를 점진적으로 미세 조정할 수 있도록 합니다. 튜토리얼 후반부에서는 Python 코드를 사용하여 반복 훈련 과정의 단계를 구현합니다.

일반적인 SOM의 사용 사례

독특한 아키텍처 덕분에 SOM은 기계 학습, 분석 및 시각화에서 여러 가지 일반적인 응용 프로그램을 가지고 있습니다.

클러스터링

SOM은 고차원 데이터를 유사한 데이터 포인트의 클러스터로 그룹화하는 데 사용됩니다. 이는 데이터 내의 고유한 구조를 식별하는 데 도움이 됩니다. 각 뉴런은 밀접하게 관련된 데이터 포인트에 매핑되며, 유사한 데이터 포인트는 동일하거나 인접한 뉴런에 매핑되어 뚜렷한 클러스터를 형성합니다.

예를 들어, 마케팅에서는 SOM을 사용하여 고객을 구매 행동에 따라 그룹화할 수 있습니다. 이는 브랜드가 다양한 고객 세그먼트(클러스터)에 맞춰 마케팅 전략을 조정할 수 있게 합니다.

차원 축소

SOM은 많은 특성 벡터를 가진 고차원 데이터를 더 적은 차원의 그리드(일반적으로 2차원 그리드)로 매핑할 수 있습니다. 이 매핑은 데이터 포인트 간의 관계를 유지하므로, 차원이 축소되면 정보의 손실 없이 복잡한 데이터 세트를 시각화하기가 더 쉬워집니다.

시각화 및 분석 작업을 더 쉽게 만드는 것 외에도, SOM은 다른 기계 학습 알고리즘을 적용하기 전에 데이터의 차원을 줄일 수 있습니다. SOM은 또한 이미지 처리에서 유사한 특성을 가진 픽셀 또는 영역을 클러스터링하여 특징의 수를 줄이는 데 사용되어 이미지 인식 및 분류 작업을 더 효율적으로 만듭니다.

이상 탐지

훈련 과정에서 대부분의 데이터 포인트는 특정 뉴런에 매핑됩니다. 이상치(어떤 클러스터에도 잘 맞지 않는 데이터 포인트)는 일반적으로 멀리 떨어진 또는 인구가 적은 뉴런에 매핑됩니다. 이러한 이상치는 학습된 클러스터에 잘 맞지 않으며 정상 데이터 포인트의 BMU에서 멀리 떨어진 뉴런에 매핑됩니다.

예를 들어, SOM 그리드에 금융 거래를 매핑하면 잠재적으로 사기 활동을 나타낼 수 있는 비정상적인 활동(이상치)을 식별할 수 있습니다.

데이터 시각화

SOM의 가장 일반적인 사용 사례 중 하나는 데이터 시각화입니다. 고차원 데이터는 시각화하기 어렵습니다. SOM은 데이터의 차원을 줄이고 이를 2차원 그리드에 투영함으로써 시각화를 용이하게 합니다. 이는 데이터에서 군집을 감지하고 원래 데이터에서 발견하기 복잡한 이상치도 찾아내는 데 도움이 될 수 있습니다.

예를 들어, 데이터 시각화는 고차원 인구 데이터를 분석하는 데 용이합니다. 데이터를 2D 그리드에 매핑하면 서로 다른 인구 집단 간의 유사성과 차이를 쉽게 파악할 수 있습니다.

SOM의 핵심 개념과 사용 사례에 대해 논의한 후, 다음 섹션에서는 Python 패키지 MiniSom을 사용하여 이를 구현하는 방법을 보여드리겠습니다.

전체 코드는 이 DataLab 노트북에서 액세스하고 실행할 수 있습니다.

환경 설정하기 for SOM

우리가 SOM을 구축하기 전에 필요한 패키지로 환경을 준비해야 합니다.

파이썬 라이브러리 설치

우리가 필요한 패키지는 다음과 같습니다:

  • MiniSom은 SOM을 생성하고 훈련시키는 NumPy 기반의 파이썬 도구입니다.
  • NumPy는 배열 분할, 고유 값 가져오기 등과 같은 수학적 함수에 접근하는 데 사용됩니다.
  • matplotlib는 데이터를 시각화하기 위해 다양한 그래프와 차트를 그리는 데 사용됩니다.
  • 데이터셋에 적용할 SOM을 가져오는데 사용되는 sklearndatasets 패키지입니다.
  • 데이터셋을 정규화하는 sklearnMinMaxScaler 패키지입니다.

다음 코드 조각은 이러한 패키지를 가져옵니다:

from minisom import MiniSom import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn.preprocessing import MinMaxScaler

데이터셋 준비

이 튜토리얼에서는 MiniSom을 사용하여 SOM을 구축하고 이를 표준 IRIS 데이터셋에서 학습합니다. 이 데이터셋은 3개의 아이리스 식물 클래스으로 구성되어 있습니다. 각 클래스는 50개의 인스턴스를 가지고 있습니다. 데이터를 준비하기 위해 다음 단계를 따릅니다: 

  • 이리스를 sklearn에서 가져옵니다
  • 데이터 벡터와 타겟 스칼라를 추출합니다. 
  • 데이터 벡터를 정규화합니다. 이 튜토리얼에서는 scikit-learn의 MinMaxScaler를 사용합니다.
  • 아이리스 식물의 세 가지 클래스에 대한 레이블 집합을 선언합니다.

다음 코드는 이러한 단계를 구현합니다:

dataset_iris = datasets.load_iris() data_iris = dataset_iris.data target_iris = dataset_iris.target data_iris_normalized = MinMaxScaler().fit_transform(data_iris) labels_iris = {1:'1', 2:'2', 3:'3'} data = data_iris_normalized target = target_iris

파이썬에서 자기 조직화 맵(SOM) 구현하기

파이썬에서 SOM을 구현하기 위해, 우리는 데이터셋에 대해 훈련하기 전에 그리드를 정의하고 초기화합니다. 그 후 훈련된 뉴런과 클러스터링된 데이터셋을 시각화할 수 있습니다.

자기 조직화 맵(SOM) 그리드 정의하기

앞서 설명한 바와 같이, SOM은 뉴런의 그리드입니다. MiniSom을 사용하여 2차원 그리드를 생성할 수 있습니다. 그리드의 X 및 Y 차원은 각 축을 따라 있는 뉴런의 수입니다. SOM 그리드를 정의하기 위해서는 다음과 같은 사항을 명시해야 합니다:

  • 그리드의 X 및 Y 차원
  • 입력 변수의 수 – 이는 데이터 행의 수입니다.

이러한 매개변수를 Python 상수로 선언합니다:

SOM_X_AXIS_NODES = 8 SOM_Y_AXIS_NODES = 8 SOM_N_VARIABLES = data.shape[1]

아래의 샘플 코드는 MiniSom을 사용하여 그리드를 선언하는 방법을 보여줍니다:

som = MiniSom(SOM_X_AXIS_NODES, SOM_Y_AXIS_NODES, SOM_N_VARIABLES)

첫 번째 두 매개변수는 X 및 Y 축을 따라 있는 뉴런의 수이며, 세 번째 매개변수는 변수의 수입니다.

우리는 SOM 그리드를 생성할 때 다른 매개변수와 하이퍼파라미터를 선언합니다. 이에 대해서는 튜토리얼 후반부에서 설명하겠습니다. 지금은 아래와 같이 이러한 매개변수를 선언하세요:

ALPHA = 0.5 DECAY_FUNC = 'linear_decay_to_zero' SIGMA0 = 1.5 SIGMA_DECAY_FUNC = 'linear_decay_to_one' NEIGHBORHOOD_FUNC = 'triangle' DISTANCE_FUNC = 'euclidean' TOPOLOGY = 'rectangular' RANDOM_SEED = 123

이 매개변수를 사용하여 SOM을 생성하세요:

som = MiniSom( SOM_X_AXIS_NODES, SOM_Y_AXIS_NODES, SOM_N_VARIABLES, sigma=SIGMA0, learning_rate=ALPHA, neighborhood_function=NEIGHBORHOOD_FUNC, activation_distance=DISTANCE_FUNC, topology=TOPOLOGY, sigma_decay_function = SIGMA_DECAY_FUNC, decay_function = DECAY_FUNC, random_seed=RANDOM_SEED, )

신경망 초기화

위의 명령은 모든 신경망에 대해 무작위 가중치를 가진 SOM을 생성합니다. 무작위 숫자 대신 데이터에서 추출한 가중치로 신경망을 초기화하면 훈련 과정이 더 효율적일 수 있습니다.

MiniSom을 사용하여 자기 조직화 맵(SOM)을 생성할 때, 데이터 기반으로 신경망의 가중치를 초기화하는 두 가지 방법이 있습니다:

  • 무작위 초기화: 뉴런의 초기 가중치는 입력 데이터에서 무작위로 선택됩니다. 우리는 .random_weights_init() 함수를 SOM에 적용하여 이를 수행합니다. 
  • PCA 초기화: 주성분 분석(PCA) 초기화는 입력 데이터의 주성분을 사용하여 가중치를 초기화합니다. 뉴런의 초기 가중치는 첫 번째 두 주성분을 포함합니다. 이는 종종 더 빠른 수렴을 가져옵니다.

이 가이드에서는 PCA 초기화를 사용합니다. SOM 가중치에 PCA 초기화를 적용하려면 아래와 같이 .pca_weights_init() 함수를 사용하세요:

som.pca_weights_init(data)

SOM 훈련

훈련 과정은 뉴런과 데이터 포인트 간의 거리를 최소화하기 위해 SOM 가중치를 업데이트합니다.

아래에서 반복 훈련 과정을 설명합니다:

  • 초기화: 모든 뉴런의 가중치 벡터는 일반적으로 무작위 값으로 초기화됩니다. 입력 데이터 분포를 샘플링하여 가중치를 초기화하는 것도 가능합니다.
  • 입력 선택: 입력 벡터가 훈련 데이터셋에서 (무작위로) 선택됩니다.
  • BMU 식별: 입력 벡터와 가장 가까운 가중치 벡터를 가진 뉴런이 BMU로 식별됩니다.
  • 이웃 업데이트: BMU와 그 이웃 뉴런들이 가중치 벡터를 업데이트합니다. 학습률과 이웃 함수는 어떤 뉴런이 얼마나 업데이트되는지를 결정합니다. 반복 단계 t에서, 입력 벡터 x와 뉴런 i의 가중치 벡터를 wi, 학습률 (t), 그리고 이웃 함수 hbi (이 함수는 BMU 뉴런 b에 대해 뉴런 i의 업데이트 정도를 정량화합니다), 뉴런 i의 가중치 업데이트 공식은 다음과 같이 표현됩니다:
  • 학습률과 이웃 반경의 감소율: 학습률과 이웃 반경은 시간이 지남에 따라 감소합니다. 초기 반복에서는 훈련 과정이 더 큰 이웃에 대해 더 큰 조정을 수행합니다. 이후 반복은 인접 뉴런의 가중치에 대해 더 작은 변화를 줌으로써 가중치를 미세 조정하는 데 도움을 줍니다. 이렇게 하면 맵이 안정화되고 수렴할 수 있습니다.

SOM을 훈련시키기 위해 모델에 입력 데이터를 제공합니다. 이를 위해 두 가지 접근 방식 중 하나를 선택할 수 있습니다:

  • 입력 데이터에서 샘플을 무작위로 선택합니다. .train_random() 함수가 이 기술을 구현합니다.
  • 입력 데이터의 벡터를 순차적으로 실행합니다. 이는 .train_batch() 함수를 사용하여 수행됩니다.

이 함수들은 입력 데이터와 반복 횟수를 매개변수로 받습니다. 이 가이드에서는 .train_random() 함수를 사용합니다. 반복 횟수를 상수로 선언하고 이를 훈련 함수에 전달합니다:

N_ITERATIONS = 5000 som.train_random(data, N_ITERATIONS, verbose=True)

스크립트를 실행하고 훈련을 완료한 후, 양자화 오류와 함께 메시지가 표시됩니다:

quantization error: 0.05357240680504421

양자화 오류는 SOM이 데이터를 양자화(차원 축소)할 때 잃어버린 정보의 양을 나타냅니다. 큰 양자화 오류는 뉴런과 데이터 포인트 간의 거리가 더 멀다는 것을 의미합니다. 또한 클러스터링의 신뢰성이 낮다는 것을 의미합니다.

시각화 SOM 뉴런

이제 훈련된 SOM 모델이 있습니다. 이를 시각화하기 위해 거리 맵(또는 U-행렬)을 사용합니다. 거리 맵은 SOM의 뉴런을 셀의 그리드로 표시합니다. 각 셀의 색상은 이웃 뉴런과의 거리를 나타냅니다.

거리 맵은 SOM과 동일한 차원의 그리드입니다. 거리 맵의 각 셀은 뉴런과 그 이웃 간의 (유클리드) 거리의 정규화된 합입니다.

SOM 거리 맵에 접근하려면 .distance_map() 함수를 사용하세요. U-행렬을 생성하기 위해 다음 단계를 따릅니다:

  • pyplot 을 사용하여 SOM과 동일한 크기의 그림을 만듭니다. 이 예제에서는 크기가 8×8입니다.
  • .pcolor() 함수를 사용하여 matplotlib로 거리 맵을 플로팅합니다. 이 예제에서는 gist_yarg 를 색상 스킴으로 사용합니다.
  • 다양한 색상을 다양한 스칼라 값에 매핑하는 colorbar를 표시합니다. 이 경우 거리가 정규화되었기 때문에 스칼라 거리 값은 0에서 1까지 범위입니다.

아래 코드는 이러한 단계를 구현합니다:

# 그리드 생성 plt.figure(figsize=(8, 8)) # 거리 맵 플로팅 plt.pcolor(som.distance_map().T, cmap='gist_yarg') # 컬러 바 표시 plt.colorbar() plt.show()

이 예에서 U-행렬은 단조로운 색상 체계를 사용합니다. 다음 가이드라인을 사용하여 이해할 수 있습니다:

  • 더 밝은 음영은 가까이 있는 뉴런을 나타내고, 더 어두운 음영은 다른 뉴런에서 더 멀리 떨어진 뉴런을 나타냅니다.
  • 더 밝은 색조의 그룹은 클러스터로 해석될 수 있습니다. 클러스터 간의 어두운 노드는 클러스터 간의 경계로 해석될 수 있습니다.

그림 1: 아이리스 데이터셋에 대해 훈련된 SOM의 U-행렬 (저자 제공 이미지)

소믈 클러스터링 결과 평가

이전 그림은 SOM의 뉴런을 그래픽적으로 설명했습니다. 이 섹션에서는 SOM이 데이터를 어떻게 클러스터링했는지 시각화하는 방법을 보여줍니다.

클러스터 식별

각 셀(뉴런)이 어떤 종류의 아이리스 식물을 나타내는지를 나타내기 위해 위의 U-행렬 위에 마커를 오버레이합니다. 이를 위해:

  • 이전과 같이 pyplot을 사용하여 8×8 도형을 만들고, 거리 맵을 그린 다음 색상 바를 표시하세요.
  • 세 가지 matplotlib 마커 배열을 지정하고, 각 아이리스 식물 클래스에 하나씩 할당하세요.
  • 세 가지 matplotlib 색상 코드 배열을 지정하고, 각 아이리스 식물 클래스에 하나씩 할당하세요.
  • 각 데이터 포인트에 대해 승리 뉴런을 반복적으로 그립니다:
    • 각 데이터 포인트에 대해 .winner( 함수를 사용하여 승리 뉴런의 (좌표) 를 결정합니다. 
    • 각 셀의 중앙에 있는 각 승리 뉴런의 위치를 ​​플롯합니다. w[0]w[1]은 각각 뉴런의 X 및 Y 좌표를 제공합니다. 셀의 중앙에 플롯하기 위해 각 좌표에 0.5가 추가됩니다. 

아래 코드는 이를 수행하는 방법을 보여줍니다:

# 거리 맵을 플롯합니다. plt.figure(figsize=(8, 8)) plt.pcolor(som.distance_map().T, cmap='gist_yarg') plt.colorbar() # 각 클래스에 대한 마커와 색상을 생성합니다. markers = ['o', 'x', '^'] colors = ['C0', 'C1', 'C2'] # 각 데이터 포인트에 대한 승리 뉴런을 플롯합니다. for count, datapoint in enumerate(data): # 승자를 가져옵니다. w = som.winner(datapoint) # 샘플 데이터 포인트의 승리 위치에 마커를 배치합니다. plt.plot(w[0]+.5, w[1]+.5, markers[target[count]-1], markerfacecolor='None', markeredgecolor=colors[target[count]-1], markersize=12, markeredgewidth=2) plt.show()

결과 이미지가 아래에 표시됩니다: 

그림 2: 클래스 마커가 겹쳐진 U-행렬 (저자 제공 이미지)

다음에 근거하여 아이리스 데이터셋 문서에 따르면, “한 클래스는 나머지 2개와 선형적으로 분리 가능하다; 후자는 서로 선형적으로 분리 불가능하다.” 위의 U-행렬에서, 이 세 개의 클래스는 세 개의 마커 – 삼각형, 원, 그리고 십자형으로 표현됩니다. 

파란 원과 주황색 십자형 사이에 명확한 경계가 없음을 주목하세요. 더욱이, 두 클래스가 많은 세포에서 같은 뉴런에 겹쳐져 있습니다. 이는 해당 뉴런이 두 클래스에서 동등한 거리에 있다는 것을 의미합니다. 

클러스터링 결과 시각화

SOM은 클러스터링 모델입니다. 유사한 데이터 포인트는 동일한 뉴런에 매핑됩니다. 동일한 클래스의 데이터 포인트는 이웃 뉴런의 클러스터에 매핑됩니다. 우리는 클러스터링 행동을 더 잘 연구하기 위해 SOM 그리드에 모든 데이터 포인트를 플로팅합니다.

다음 단계는 이 산점도를 만드는 방법을 설명합니다:

  • 각 데이터 포인트에 대해 승리한 뉴런의 X 및 Y 좌표를 가져옵니다.
  • 거리 맵을 플로팅합니다. 이는 그림 1에서 했던 것과 같습니다.
  • 모든 데이터 포인트에 대한 승리 뉴런의 산점도를 만들기 위해 plt.scatter()를 사용하세요. 같은 셀 내의 데이터 포인트 간 겹침을 피하기 위해 각 포인트에 무작위 오프셋을 추가하세요.

아래 코드에서 이러한 단계를 구현합니다:

# 각 데이터 포인트에 대한 승리 뉴런의 X 및 Y 좌표 가져오기w_x, w_y = zip(*[som.winner(d) for d in data]) w_x = np.array(w_x) w_y = np.array(w_y) # 거리 맵 플롯하기 plt.figure(figsize=(8, 8)) plt.pcolor(som.distance_map().T, cmap='gist_yarg', alpha=.2) plt.colorbar() # 각 데이터 포인트에 대한 모든 승리 뉴런의 산점도 만들기 # 겹침을 피하기 위해 각 포인트에 무작위 오프셋 추가하기 for c in np.unique(target): idx_target = target==c plt.scatter(w_x[idx_target]+.5+(np.random.rand(np.sum(idx_target))-.5)*.8, w_y[idx_target]+.5+(np.random.rand(np.sum(idx_target))-.5)*.8, s=50, c=colors[c-1], label=labels_iris[c+1] ) plt.legend(loc='upper right') plt.grid() plt.show()

다음 그래프는 출력된 산점도를 보여줍니다:

그림 3: 셀 내 데이터 포인트의 산점도 (저자 제공)

위의 산점도를 보면 다음과 같은 점을 관찰할 수 있습니다:

  • 일부 셀에는 파란색과 주황색 점이 모두 포함되어 있습니다.
  • 초록색 점은 나머지 데이터와 명확하게 구분되지만, 파란색과 주황색 점은 깔끔하게 구분되지 않습니다.
  • 위의 관찰 결과는 아이리스 데이터셋의 세 개 클러스터 중 오직 하나만 명확한 경계를 가지고 있다는 사실과 일치합니다.
  • 그림 1에서 클러스터 사이의 어두운 노드(클러스터 간의 경계로 해석될 수 있음)는 산점도의 빈 셀과 일치합니다.

전체 코드는 이 DataLab 노트북에서 접근하고 실행할 수 있습니다.

조정하는 SOM 모델

이전 섹션에서는 SOM 모델을 생성하고 훈련하는 방법과 결과를 시각적으로 연구하는 방법을 보여주었습니다. 이번 섹션에서는 SOM 모델의 성능을 조정하는 방법에 대해 논의합니다.

조정해야 할 주요 하이퍼파라미터

모든 머신 러닝 모델과 마찬가지로, 하이퍼파라미터는 모델의 성능에 상당한 영향을 미칩니다.

SOM을 훈련할 때 중요한 하이퍼파라미터는 다음과 같습니다:

  • 그리드 크기는 맵의 크기를 결정합니다. AxB의 그리드 크기를 가진 맵의 뉴런 수는 A*B입니다.
  • 학습률는 매 반복마다 가중치가 얼마나 변경되는지를 결정합니다. 우리는 초기 학습률을 설정하고, 그것은 감소 함수에 따라 시간이 지남에 따라 감소합니다.
  • 감소 함수는 각 반복에서 학습률이 얼마나 감소되는지를 결정합니다.
  • 이웃 함수는 어떤 뉴런이 BMU의 이웃으로 간주될지를 지정하는 수학적 함수입니다.
  • 표준 편차는 이웃 함수의 분포를 지정합니다. 예를 들어, 표준 편차가 높은 가우시안 이웃 함수는 표준 편차가 낮은 동일한 함수보다 더 큰 이웃을 가집니다. 우리는 초기 표준 편차를 설정하며, 이는 시그마 감소 함수에 따라 시간이 지남에 따라 감소합니다.
  • 시그마 감쇠 함수는 각 반복에서 표준 편차가 얼마나 감소되는지를 조절합니다.
  • 훈련 반복 횟수는 가중치가 업데이트되는 횟수를 결정합니다. 각 훈련 반복에서 뉴런 가중치는 한 번 업데이트됩니다.
  • 거리 함수는 뉴런과 데이터 포인트 간의 거리를 계산하는 수학적 함수입니다. 
  • 토폴로지 는 그리드 구조의 레이아웃을 결정합니다. 그리드 내의 뉴런은 직사각형 또는 육각형 패턴으로 배열될 수 있습니다. 

다음 섹션에서는 이러한 하이퍼파라미터의 값을 설정하기 위한 지침에 대해 논의합니다. 

하이퍼파라미터 조정의 영향

하이퍼파라미터 값은 모델과 데이터셋에 따라 결정되어야 합니다. 어느 정도까지는 이러한 값을 결정하는 과정이 시행착오의 연속입니다. 이 섹션에서는 각 하이퍼파라미터 조정을 위한 지침을 제공합니다. 각 하이퍼파라미터 옆에 샘플 코드에서 사용되는 해당 파이썬 상수를 괄호 안에 언급합니다.

  • 그리드 크기 (SOM_X_AXIS_NODESSOM_X_AXIS_NODES): 그리드 크기는 데이터셋의 크기에 따라 달라집니다. 일반적인 규칙으로는 크기 N의 데이터셋이 주어졌을 때, 그리드는 대략 5*sqrt(N) 개의 뉴런을 포함해야 합니다. 예를 들어, 데이터셋에 150개의 샘플이 있다면, 그리드는 5*sqrt(150) = 약 61개의 뉴런을 포함해야 합니다. 이 튜토리얼에서는 아이리스(Iris) 데이터셋이 150개의 행을 가지고 있으며, 8×8 그리드를 사용합니다. 
  • 초기 학습률 (ALPHA): 높은 비율은 수렴 속도를 높이고, 낮은 비율은 초기 반복 후 미세 조정을 위해 사용됩니다. 초기 학습률은 빠른 적응을 가능하게 할 만큼 충분히 커야 하지만 최적의 가중치 값을 초과하지 않을 정도로 커서는 안 됩니다. 이 기사에서는 초기 학습률을 0.5로 설정합니다. 
  • 초기 표준 편차 (SIGMA0): 이 값은 이웃의 초기 크기 또는 분포를 결정합니다. 더 큰 값은 더 많은 글로벌 패턴을 고려합니다. 이 예제에서는 시작 표준 편차를 1.5로 설정합니다. 
  • 데코레이션 비율(DECAY_FUNC) 및 시그마 감쇠 비율(SIGMA_DECAY_FUNC)에 대해, 세 가지 유형의 감쇠 함수 중 하나를 선택할 수 있습니다:
    • 역감쇠: 이 함수는 데이터에 전역 및 지역 패턴이 모두 포함된 경우에 적합합니다. 이러한 경우, 지역 패턴에 집중하기 전에 폭넓은 학습의 긴 단계가 필요합니다.
    • 선형 감쇠: 이는 데이터셋에서 안정적이고 균일한 이웃 크기 또는 학습 속도 감소를 원할 때 좋습니다. 데이터에 큰 세부 조정이 필요하지 않은 경우 유용합니다.
    • 점근적 감쇠: 이 함수는 데이터가 복잡하고 고차원일 때 유용합니다. 이러한 경우, 세부 사항으로 점진적으로 전환하기 전에 전역 탐색에 더 많은 시간을 할애하는 것이 좋습니다.
  • 이웃 함수 (NEIGHBORHOOD_FUNC): 이웃 함수의 기본 선택은 가우시안 함수입니다. 아래에 설명된 다른 함수들도 사용됩니다. 
    • 가우시안 (기본값): 이것은 종 모양의 곡선입니다. 뉴런이 업데이트되는 정도는 승리한 뉴런과의 거리가 증가할수록 부드럽게 감소합니다. 이는 부드럽고 연속적인 전환을 제공하며 데이터의 위상 구조를 보존합니다. 안정적이고 예측 가능한 동작으로 인해 대부분의 일반적인 용도에 적합합니다.
    • 버블: 이 기능은 고정 폭 이웃을 생성합니다. 이 이웃 내의 모든 뉴런은 동등하게 업데이트되며, 이 이웃 밖의 뉴런은 업데이트되지 않습니다(주어진 데이터 포인트에 대해). 계산적으로 더 저렴하고 구현하기 쉽습니다. 날카로운 이웃 경계가 효과적인 클러스터링을 저해하지 않는 작은 맵에서 유용합니다.
    • 멕시코 모자: 중앙에 긍정적인 영역이 있고 그 주위에 부정적인 영역이 있습니다. BMU에 가까운 뉴런은 데이터 포인트에 더 가까워지도록 업데이트되고, 멀리 있는 뉴런은 데이터 포인트에서 멀어지도록 업데이트됩니다. 이 기술은 대비를 향상시키고 맵의 특징을 선명하게 합니다. 뚜렷한 클러스터를 강조하기 때문에, 클러스터의 명확한 분리가 필요한 패턴 인식 작업에서 효과적입니다.
    • 삼각형: 이 기능은 BMU가 가장 큰 영향을 미치는 삼각형으로 이웃 크기를 정의합니다. BMU에서의 거리에 따라 선형적으로 감소합니다. 이는 이미지, 음성 또는 시계열 데이터와 같이 이웃 데이터 포인트가 유사한 특성을 공유할 것으로 예상되는 클러스터 또는 특성 간의 점진적인 전환을 통해 데이터를 클러스터링하는 데 사용됩니다.
  • 거리 함수 (DISTANCE_FUNC): 뉴런과 데이터 포인트 간의 거리를 측정하기 위해 4가지 방법 중에서 선택할 수 있습니다:
    • 유클리디안 거리 (기본 선택): 데이터가 연속적이고 직선 거리를 측정하고 싶을 때 유용합니다. 데이터 포인트가 균일하게 분포되어 있고 공간적으로 관련이 있는 경우에 가장 적합합니다.
    • 코사인 거리: 텍스트나 고차원 희소 데이터의 경우 벡터 간 각도가 크기보다 중요할 때 좋은 선택입니다. 데이터의 방향성을 비교하는 데 유용합니다.
    • 맨해튼 거리: 데이터 포인트가 격자나 격자 (예: 도시 블록) 상에 있는 경우 이상적입니다. 이는 유클리디안 거리보다 이상치에 덜 민감합니다.
    • 체비셰프 거리: 이동이 모든 방향으로 발생할 수 있는 상황에 적합합니다 (예: 체스판 거리). 최대 축 차이를 우선시해야 하는 이산 공간에서 유용합니다.
  • 위상학 (TOPOLOGY): 그리드에서 뉴런은 육각형 또는 직사각형 구조로 배열될 수 있습니다:
    • 사각형 (기본): 각 뉴런은 4개의 인접한 이웃을 가집니다. 데이터에 명확한 공간적 관계가 없을 때 적합한 선택입니다. 또한 계산적으로 더 간단합니다.
    • 육각형: 각 뉴런은 6개의 이웃을 가집니다. 데이터가 육각형 그리드로 더 잘 표현되는 공간적 관계를 가질 경우 선호되는 옵션입니다. 이는 원형 또는 각형 데이터 분포의 경우입니다.
  • 훈련 반복 횟수 (N_ITERATIONS): 원칙적으로, 더 긴 훈련 시간은 낮은 오류와 입력 데이터에 대한 가중치의 더 나은 정렬로 이어집니다. 그러나 모델의 성능은 반복 횟수가 증가함에 따라 점근적으로 증가합니다. 따라서 특정 반복 횟수 이후에는 후속 상호작용에서 성능 향상이 미미합니다. 올바른 반복 횟수를 결정하는 데는 약간의 실험이 필요합니다. 이 튜토리얼에서는 모델을 5000회 반복하여 훈련합니다.

하이퍼파라미터의 올바른 구성을 결정하기 위해, 데이터의 더 작은 하위 집합에서 다양한 옵션을 실험해볼 것을 권장합니다.

결론

자기 조직화 맵(Self-organizing maps, SOM)은 비지도 학습을 위한 강력한 도구입니다. 이 도구는 클러스터링, 차원 축소, 이상 탐지 및 데이터 시각화에 사용됩니다. SOM은 고차원 데이터의 위상적 특성을 보존하고 이를 저차원 그리드에 표현하기 때문에 복잡한 데이터 세트를 쉽게 시각화하고 해석할 수 있습니다.

이 튜토리얼에서는 SOM의 기본 원리를 논의하고 MiniSom 파이썬 라이브러리를 사용하여 SOM을 구현하는 방법을 보여주었습니다. 또한 결과를 시각적으로 분석하는 방법을 시연하고 SOM을 훈련하고 성능을 미세 조정하는 데 사용되는 중요한 하이퍼파라미터에 대해 설명했습니다.

Source:
https://www.datacamp.com/tutorial/self-organizing-maps