K-평균 군집화 가정 탐색

Beginner

This tutorial is from open-source community. Access the source code

소개

이 실습에서는 k-평균 군집화 알고리즘과 그 가정에 대해 살펴볼 것입니다. 다양한 분포를 가진 데이터를 생성하고 k-평균이 이 데이터를 어떻게 클러스터로 분할하는지 시각화할 것입니다. 또한, 알고리즘의 한계와 이를 극복하기 위한 해결책에 대해 논의할 것입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근할 수 있습니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사는 자동화될 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 생성

scikit-learn 의 make_blobs 함수를 사용하여 다양한 분포를 가진 서로 다른 데이터셋을 생성할 것입니다. 다음 코드 블록에서는 네 가지 데이터셋을 생성합니다.

  • 가우시안 볼록 혼합
  • 이방성 분포 볼록
  • 불균일 분산 볼록
  • 불균일 크기 볼록
import numpy as np
from sklearn.datasets import make_blobs

n_samples = 1500
random_state = 170
transformation = [[0.60834549, -0.63667341], [-0.40887718, 0.85253229]]

X, y = make_blobs(n_samples=n_samples, random_state=random_state)
X_aniso = np.dot(X, transformation)  ## 이방성 볼록
X_varied, y_varied = make_blobs(
    n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)  ## 불균일 분산
X_filtered = np.vstack(
    (X[y == 0][:500], X[y == 1][:100], X[y == 2][:10])
)  ## 불균일 크기 볼록
y_filtered = [0] * 500 + [1] * 100 + [2] * 10

데이터 시각화

Matplotlib 을 사용하여 생성된 데이터셋을 시각화할 것입니다. 다음 코드 블록에서는 각 데이터셋의 실제 클러스터를 보여주는 2x2 플롯을 만듭니다.

import matplotlib.pyplot as plt

fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))

axs[0, 0].scatter(X[:, 0], X[:, 1], c=y)
axs[0, 0].set_title("가우시안 볼록 혼합")

axs[0, 1].scatter(X_aniso[:, 0], X_aniso[:, 1], c=y)
axs[0, 1].set_title("이방성 분포 볼록")

axs[1, 0].scatter(X_varied[:, 0], X_varied[:, 1], c=y_varied)
axs[1, 0].set_title("불균일 분산")

axs[1, 1].scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_filtered)
axs[1, 1].set_title("불균일 크기 볼록")

plt.suptitle("실제 클러스터").set_y(0.95)
plt.show()

K-평균 군집화

scikit-learn 의 KMeans 클래스를 사용하여 데이터를 군집화할 것입니다. 다음 코드 블록에서는 각 데이터셋에 대한 K-평균으로 얻은 클러스터를 보여주는 2x2 플롯을 만듭니다.

from sklearn.cluster import KMeans

common_params = {
    "n_init": "auto",
    "random_state": random_state,
}

fig, axs = plt.subplots(nrows=2, ncols=2, figsize=(12, 12))

y_pred = KMeans(n_clusters=2, **common_params).fit_predict(X)
axs[0, 0].scatter(X[:, 0], X[:, 1], c=y_pred)
axs[0, 0].set_title("적절하지 않은 클러스터 수")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_aniso)
axs[0, 1].scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
axs[0, 1].set_title("이방성 분포 볼록")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_varied)
axs[1, 0].scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
axs[1, 0].set_title("불균일 분산")

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X_filtered)
axs[1, 1].scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
axs[1, 1].set_title("불균일 크기 볼록")

plt.suptitle("예상치 못한 KMeans 클러스터").set_y(0.95)
plt.show()

가능한 해결책

K-평균 군집화의 한계를 극복하기 위한 몇 가지 해결책을 논의할 것입니다. 다음 코드 블록에서는 첫 번째 데이터셋에 대한 올바른 클러스터 수를 찾는 방법과 불균일한 크기의 볼록을 처리하기 위해 여러 번의 랜덤 초기화를 수행하는 방법을 보여줍니다.

y_pred = KMeans(n_clusters=3, **common_params).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title("최적의 클러스터 수")
plt.show()

y_pred = KMeans(n_clusters=3, n_init=10, random_state=random_state).fit_predict(
    X_filtered
)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
plt.title("불균일 크기 볼록 \n여러 초기화")
plt.show()

가우시안 혼합 모델

이방성 및 불균일 분산 분포를 처리할 수 있는 가우시안 혼합 모델 (Gaussian Mixture Model) 의 사용법을 살펴볼 것입니다. 다음 코드 블록에서는 GaussianMixture를 사용하여 두 번째 및 세 번째 데이터셋을 군집화합니다.

from sklearn.mixture import GaussianMixture

fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, figsize=(12, 6))

y_pred = GaussianMixture(n_components=3).fit_predict(X_aniso)
ax1.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
ax1.set_title("이방성 분포 볼록")

y_pred = GaussianMixture(n_components=3).fit_predict(X_varied)
ax2.scatter(X_varied[:, 0], X_varied[:, 1], c=y_pred)
ax2.set_title("불균일 분산")

plt.suptitle("가우시안 혼합 클러스터").set_y(0.95)
plt.show()

요약

이 실험에서는 k-평균 군집화 알고리즘과 그 가정들을 살펴보았습니다. 다양한 분포를 가진 여러 데이터셋을 생성하고, k-평균이 이 데이터를 어떻게 클러스터로 분할하는지 시각화했습니다. 또한, 알고리즘의 한계점과 이를 극복하기 위한 몇 가지 해결책, 즉 올바른 클러스터 수 찾기, 랜덤 초기화 횟수 증가, 가우시안 혼합 모델 사용 등에 대해 논의했습니다.