정답(레이블)이 없는 데이터를 기반으로 학습하는 머신러닝의 한 방법
주어진 데이터에서 유사한 특성을 가진 데이터 포인트들을 그룹으로 묶는 것
주어진 데이터를 K개의 클러스터로 나누는 비지도 학습 방법
① 초기 클러스터 중심(Centroid) 설정: 클러스터의 개수 K를 사용자가 미리 설정 -> 무작위나 데이터를 기반으로 선택
② 데이터 포인트 할당: 각 데이터 포인트를 가장 가까운 클러스터 중심에 할당 -> 가까운 중심에 속하는 데이터 포인트가 하나의 클러스터를 형성
③ 클러스터 중심 재계산: 각 클러스터에 속한 데이터 포인트들의 평균 위치를 계산 -> 새로운 클러스터 중심 설정
④ 반복: 위 과정을 반복 -> 클러스터 중심이 더 이상 변하지 않거나, 최대 반복 횟수에 도달하면 종료
① 데이터 준비: 군집화를 수행할 데이터 준비 및 정규화
② K값 선택: 원하는 클러스터 개수 K 결정
③ 알고리즘 실행: K-Means 알고리즘 적용하여 데이터 클러스터링
④ 결과 평가 및 시각화: 각 클러스터의 품질을 평가하고 시각적으로 확인
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
# 1. 데이터 생성
n_samples = 300
n_cluster = 3
x, y = make_blobs(n_samples=n_samples, centers=n_cluster, random_state=42, cluster_std=1.0)
# 2. 데이터 그래프 생성: 군집화 하기 전, 중앙값 구하기 전
plt.scatter(x[:, 0], x[:, 1], s=30, c='gray', label='original data')
plt.title('original data')
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
# 3. KMeans 객체 생성 학습
kmeans = KMeans(n_clusters=3, random_state=42)
# 4. 레이블 값 반환
cluster_labels = kmeans.fit_predict(x)
# 5. 군집 결과 시각화
plt.scatter(x[:, 0], x[:, 1], c=cluster_labels, cmap='viridis', s=30, label='cluster data')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='red', marker='x')
plt.title('Clustering Data')
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
# 6. 최적의 K값 찾기
wcss = []
k_range = range(1, 10)
for k in k_range:
kmeans_temp = KMeans(n_clusters=k, random_state=42)
kmeans_temp.fit(x)
wcss.append(kmeans_temp.inertia_)
plt.plot(k_range, wcss, marker='o')
plt.title('Elbow Method for Optimal K')
plt.xlabel('K')
plt.ylabel('WCSS')
plt.show()
클러스터링 결과가 얼마나 잘 나왔는지 평가
데이터 포인트가 클러스터와 얼마나 잘 응집되어 있는지, 다른 클러스터와는 얼마나 잘 분리되어 있는지 나타냄
ㄴ> 클러스터의 응집도와 분리도 동시에 평가 가능
계산 공식 -> s(i) = b(i) - a(i) / max(a(i), b(i))
a(i): 데이터 포인트 i와 같은 클러스터 내 다른 포인트 간 평균 거리 (응집도)
b(i): 데이터 포인트 i와 가장 가까운 다른 클러스터 간 평균 거리 (분리도)
s(i): 1이면 응집도/분리도 높음, 0이면 데이터 포인터가 경계에 가까움 (어느 클러스터에 속하는지 불확실), 음수면 잘못된 클러스터에 속했을 가능성 높음
전체 실루엣 점수: 모든 데이터 포인트의 s(i) 값 평균
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, silhouette_samples
# 1. 데이터 생성
n_samples = 300
n_cluster = 3
x, y = make_blobs(n_samples=n_samples, centers=n_cluster, random_state=42, cluster_std=1.0)
# 2. 데이터 그래프 생성: 군집화 하기 전, 중앙값 구하기 전
plt.scatter(x[:, 0], x[:, 1], s=30, c='gray', label='original data')
plt.title('original data')
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
# 3. KMeans 객체 생성 학습
kmeans = KMeans(n_clusters=3, random_state=42)
# 4. 레이블 값 반환
cluster_labels = kmeans.fit_predict(x)
# 5. 군집 결과 시각화
plt.scatter(x[:, 0], x[:, 1], c=cluster_labels, cmap='viridis', s=30, label='cluster data')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=200, c='red', marker='x')
plt.title('Clustering Data')
plt.xlabel('F1')
plt.ylabel('F2')
plt.show()
# 6. 실루엣 스코어
sil_avg = silhouette_score(x, cluster_labels)
print(sil_avg)
# 시각화를 위한 점수 계산
sil_value = silhouette_samples(x, cluster_labels)
y_lower = 10
for i in range(4):
ith_cluster_sil_values = sil_value[cluster_labels == i]
ith_cluster_sil_values.sort()
size_cluster_i = ith_cluster_sil_values.shape[0]
y_upper = y_lower + size_cluster_i
# 막대그래프 추가
plt.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_sil_values)
plt.text(-0.05, y_lower + 0.5*size_cluster_i, str(i))
y_lower = y_upper + 10
plt.axvline(x=sil_avg, color='red', linestyle='--')
plt.title('silhouette plot')
plt.show()
① 각 데이터 포인트를 하나의 클러스터로 간주
② 두 클러스터 간 거리를 계산
③ 가장 가까운 두 클러스터를 병합
④ 클러스터가 하나가 될 때까지 반복
from sklearn.datasets import make_blobs
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
import matplotlib.pyplot as plt
# 1. 데이터 생성
data, _ = make_blobs(n_samples=200, centers=4, cluster_std=0.7, random_state=42)
# 2. 데이터 시각화
plt.scatter(data[:, 0], data[:, 1], s=30, color='gray', label="Original Data")
plt.title("Generated Data")
plt.xlabel("F1")
plt.ylabel("F2")
plt.legend()
# 3. 계층적 군집화 적용
linked = linkage(data, method='ward')
# 4. 덴드로그램 시각화
plt.figure(figsize=(10, 7))
dendrogram(linked, truncate_mode='lastp', p=10, leaf_rotation=90, leaf_font_size=10)
plt.title("Hierarchical Clustering Dendrogram")
plt.xlabel("Cluster Size")
plt.ylabel("Distance")
plt.show()
# 4. 클러스터 형성
cluster_labels = fcluster(linked, t=7, criterion='distance')
# 5. 결과 시각화
plt.scatter(data[:, 0], data[:, 1], c=cluster_labels, cmap='rainbow', s=30)
plt.title("Hierarchical Clustering Results")
plt.xlabel("F1")
plt.ylabel("F2")
plt.show()
① 각 데이터 포인트에 대해 𝜖-이웃을 계산
② 𝜖-이웃 내 데이터 포인트 수가 MinPts 이상 -> 핵심(Core) 포인트로 간주
③ 핵심 포인트와 연결된 이웃 데이터는 같은 클러스터로 그룹화
④ 밀도가 낮은 포인트 -> 노이즈로 분류
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.cluster import DBSCAN
# 1. 데이터 생성
data, _ = make_moons(n_samples=300, noise=0.05, random_state=42)
# 2. 데이터 시각화
plt.scatter(data[:, 0], data[:, 1], s=30, color='gray', label="Original Data")
plt.title("Generated Data")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.legend()
plt.show()
# 3. DBSCAN 모델 생성 및 학습
dbscan = DBSCAN(eps=0.2, min_samples=5)
# 4. 데이터에 대한 클러스터 예측
cluster_labels = dbscan.fit_predict(data)
# 5. 클러스터링 결과 시각화
plt.scatter(data[:, 0], data[:, 1], c=cluster_labels, cmap='viridis', s=30)
plt.title("DBSCAN Clustering Results")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.colorbar(label="Cluster Label")
plt.show()
# 6. 클러스터링 결과 요약
unique_labels = set(cluster_labels)
print(f"Unique Clusters: {unique_labels}")
# 클러스터별 데이터 포인트 수 출력
for label in unique_labels:
count = (cluster_labels == label).sum()
if label == -1:
print(f"Noise points: {count}")
else:
print(f"Cluster {label}: {count} points")