[혼공머신]6-2
k-평균 (K-Means)
k-평균 알고리즘은 비지도 학습에서 매우 흔히 사용되는 클러스터링 방법입니다. 이 알고리즘의 주 목적은 데이터를 k개의 클러스터로 그룹화하는 것이며, 각 클러스터는 서로 비슷한 특성을 가진 데이터 포인트들로 구성됩니다. 알고리즘의 기본적인 단계는 다음과 같습니다:
- 초기화: 먼저 클러스터의 수 ( k )를 정하고, 데이터 포인트들 중에서 무작위로 ( k )개의 포인트를 클러스터의 중심(센트로이드)으로 선택합니다.
- 할당: 각 데이터 포인트를 가장 가까운 센트로이드에 할당하여 클러스터를 형성합니다.
- 업데이트: 각 클러스터의 평균 위치로 센트로이드를 업데이트합니다.
- 이 할당과 업데이트 과정을 센트로이드의 변화가 없거나, 사용자가 설정한 최대 반복 횟수에 도달할 때까지 반복합니다.
이 알고리즘은 특히 대용량 데이터 세트에 효과적이며, 다양한 응용 분야에서 클러스터링을 위해 널리 사용됩니다.
1. KMeans 클래스
scikit-learn
라이브러리의 KMeans
클래스는 Python에서 k-평균 알고리즘을 구현할 때 사용됩니다. 이 클래스의 주요 매개변수는 다음과 같습니다:
- n_clusters: 클러스터의 개수 ( k )를 정합니다. 기본값은 8입니다.
- n_init: 초기 센트로이드 설정 후 알고리즘을 반복 실행하는 횟수입니다. 최적의 결과를 얻기 위해 여러 번 실행 후 최소 이너셔를 가진 결과를 선택합니다. 사이킷런 1.4에서는 이 값이 ‘auto’로 설정될 예정이며, 이는 알고리즘의 실행을 자동으로 조정합니다.
- max_iter: 한 번의 실행에서 최적의 센트로이드를 찾기 위해 반복할 수 있는 최대 횟수입니다. 기본값은 200입니다.
# 데이터 로드 및 전처리
!wget https://bit.ly/fruits_300_data -O fruits_300.npy
import numpy as np
fruits = np.load('fruits_300.npy')
fruits_2d = fruits.reshape(-1, 100*100)
# KMeans 클러스터링 수행
from sklearn.cluster import KMeans
km = KMeans(n_clusters=3, random_state=42)
km.fit(fruits_2d)
2. 클러스터 중심
클러스터 중심, 또는 센트로이드는 해당 클러스터에 속한 모든 샘플의 특성 평균값으로 정의됩니다. 클러스터링 과정에서 이 센트로이드는 각 클러스터의 “중심점”으로 작용하며, 새로운 데이터 포인트를 클러스터링 할 때 참조점으로 사용됩니다. 센트로이드는 클러스터의 대표적인 특성을 나타내므로, 각 클러스터의 특징을 이해하는 데 중요한 역할을 합니다.
# 클러스터 레이블 출력 및 개수 확인
print(km.labels_)
print(np.unique(km.labels_, return_counts=True))
# 클러스터링 결과 시각화]
import matplotlib.pyplot as plt
def draw_fruits(arr, ratio=1):
# 코드는 배열의 이미지를 그리는 함수를 정의
draw_fruits(fruits[km.labels_==0])
draw_fruits(fruits[km.labels_==1])
draw_fruits(fruits[km.labels_==2])
draw_fruits(km.cluster_centers_.reshape(-1, 100, 100), ratio=3)
3. 최적의 k 찾기
클러스터의 수 ( k )를 결정하는 것은 k-평균 알고리즘에서 중요한 결정 중 하나입니다. 너무 많은 클러스터는 과적합을, 너무 적은 클러스터는 과소적합을 초래할 수 있습니다. 최적의 ( k )를 찾기 위한 하나의 방법은 엘보우 방법입니다. 이 방법에서는 다양한 ( k )값에 대해 이너셔를 계산하고, 이너셔가 급격히 감소하는 지점을 찾습니다. 이 “꺾이는 지점”은 클러스터 수가 적절한 수준에 도달했음을 나타내며, 여기서 추가적인 클러스터가 큰 이득을 주지 않는다는 신호로 해석됩니다.
이와 같은 분석을 통해 데이터를 효과적으로 이해하고, 구조화하는 데 도움을 줄 수 있습니다.
# 새로운 샘플에 대한 변환 및 예측
print(km.transform(fruits_2d[100:101]))
print(km.predict(fruits_2d[100:101]))
draw_fruits(fruits[100:101])
# 최적의 클러스터 수를 찾기 위한 엘보우 방법
inertia = []
for k in range(2, 7):
km = KMeans(n_clusters=k, n_init='auto', random_state=42)
km.fit(fruits_2d)
inertia.append(km.inertia_)
plt.plot(range(2, 7), inertia)
plt.xlabel('k')
plt.ylabel('inertia')
plt.show()
댓글남기기