이번 글은 코드잇 강의를 수강하면서 배운 내용을 주로 하여 정리되어 있습니다. (코드잇 스프린트 데이터 애널리스트 트랙 1기 훈련생)
K-Means
K-Means란?
K-Means는 k개의 클러스터로 나누고, 각 클러스터의 중심을 반복적으로 갱신하여 최적의 클러스터 구성을 찾는 알고리즘입니다.
K-Means의 기본 개념은 유사한 데이터는 Centroid(중심점)로부터 가까이에 모여있다는 점입니다.
k-means 클러스터링 동작 과정
- Centroid 배치 :
- 클러스터 개수 k를 설정합니다. (예시: k=2)
- k만큼의 Centroid를 생성하여 임의로 배치합니다.
- 클러스터 형성 :
- 각 데이터와 Centroid 사이의 거리를 계산하여, 가까운 Centroid에 데이터들을 할당하여 클러스터를 형성합니다.
- Centroid 위치 갱신 :
- 클러스터 내 데이터들의 중심(평균값)을 계산하여 Centroid의 위치를 이동시킵니다.
- 클러스터 재형성 :
- 새롭게 위치한 Centroid를 기준으로, 각 데이터와의 거리를 다시 계산하여 가까운 데이터들을 클러스터로 묶습니다.
- Centroid 위치 갱신 :
- 새롭게 형성된 클러스터의 중심으로 Centroid를 다시 이동시킵니다.
- 위 과정의 반복 :
- 하지만 실제 데이터에서는 최적의 클러스터를 쉽게 찾지 못하기 때문에 위의 단계를 여러 번 반복하여 Centroid의 위치를 계속 갱신합니다.
- Centroid가 더 이상 위치를 갱신하지 않으면, 최종 클러스터가 형성됩니다.
K-means의 특징
- 간단함과 효율성: 비교적 간단하고 큰 데이터 세트에서도 효율적으로 작동합니다.
- 초기화의 중요성: 초기 클러스터 중심 선택이 결과에 큰 영향을 미칩니다.
- 유클리디안 거리 사용: 데이터 포인트 간의 거리를 측정할 때 주로 유클리디안 거리를 사용합니다.
- 클러스터 개수 k의 사전 설정 필요: 클러스터의 개수 k를 미리 지정해야 합니다.
- 클러스터 구역: 클러스터 구역은 중심점들 간의 수직 중심 영역입니다.
모델과 학습
모델(Model)
- 모델의 두 가지 의미
- 분석 방법론: 특정 분석 기법이나 알고리즘을 의미합니다. 예를 들어, k-means 클러스터링.
- 프로그램: 분석 방법을 적용하고, 그 결과를 저장할 수 있는 소프트웨어나 프로그램.
학습(Learning)
- 모델에게 데이터를 전달하여 분석하게 하는 과정.
k-means 모델 학습시키기
- 즉, 위 개념을 통해 생각해보면 k-means 모델을 학습시킨다는 것은 k-means 분석법이 저장된 프로그램에게 데이터를 전달하여, 그 결과를 얻고 저장하는 것을 의미합니다.
K-means 모델 학습
# 라이브러리 불러오기
from sklearn.cluster import KMeans
# 모델 선언
model = KMeans(n_clusters=3, random_state=123)
# n_clusters: 클러스터 개수(k)를 설정 (예시에서는 3으로 설정) k를 몇으로 하냐에 따라 k-means 모델의 성능이 크게 달라짐.
# random_state: 모델의 일관된 결과를 위해 난수 설정 (예시에서는 123).
# 모델 학습
model.fit(df)
# 각 데이터가 어떤 클러스터로 구분됐는지 표시하기 위해 새로운 라벨을 추가하기
df['label'] = model.predict(df)
# predict() 함수를 사용해 각 데이터가 어떤 클러스터로 분류되었는지 예측하고, 결과를 데이터프레임에 새로운 열로 추가.
# 각 군집의 중심점과 클러스터 시각화
centers = model.cluster_centers_
sns.scatterplot(x=df['total_view_cnt'], y=df['total_time'], hue=df['label'], s=200, palette='bright')
sns.scatterplot(x=centers[:,0], y=centers[:,1], color='black', alpha=0.8, s=400)
Elbow Method
Elbow Method는 최적 클러스터의 수 k를 정할 때 사용하는 방법 중 하나입니다.
- 각 k 값에 대한 Inertia(관성) 또는 WCSS (Within-Cluster Sum of Squares)를 계산하여, Inertia가 급격히 감소하는 지점(Elbow Point)을 최적의 k로 선택합니다.
- Inertia : 각 데이터 포인트와 해당 클러스터의 중심점(Centroid) 간의 거리의 제곱합. (각 클러스터 내에서 중심점과 클러스터 내 데이터 사이의 거리를 제곱해서 더한 값)
- WCSS : 클러스터 내 데이터 포인트들이 중심점으로부터 얼마나 퍼져 있는지를 나타내는 지표
# 모델의 inertia 값 확인하기
print(model.inertia_)
k-means 클러스터링에서 k의 역할
- k는 클러스터의 개수를 나타내며, k-means 알고리즘은 데이터를 k개의 클러스터로 나눕니다.
- 올바른 k를 선택하지 않으면 클러스터링 결과가 왜곡될 수 있습니다.
- k가 너무 작으면: 서로 다른 특성을 가진 데이터가 같은 클러스터에 속할 수 있습니다.
- k가 너무 크면: 유사한 특성을 가진 데이터가 여러 클러스터로 나뉠 수 있습니다.
- 영향
- 모델의 성능: 적절한 k를 선택해야 클러스터링의 품질이 높아지고, 데이터의 특성을 잘 반영한 그룹을 만들 수 있습니다.
- 해석 가능성: 적절한 k를 선택해야 클러스터링 결과를 더 쉽게 해석하고 활용할 수 있습니다.
Elbow Method 과정(inertia 값을 계산하고, 해당 값들을 시각화)
- 여러 k 값에 대해 k-means 알고리즘 적용: k=1부터 시작하여 적절한 범위의 k 값에 대해 k-means 알고리즘을 적용합니다.
- 각 k 값에 대한 Inertia 계산: 각 k 값에 대한 Inertia를 계산합니다.(클러스터 개수를 늘려가며 inertia값을 추적한다.)
- Inertia 값 시각화: k 값에 따른 Inertia 값을 그래프로 그립니다.
- Elbow Point 찾기: 그래프에서 Inertia의 감소가 완만해지기 시작하는 지점을 찾습니다. 이 지점이 Elbow Point이며, 최적의 k 값입니다. (명확한 기준은 아니며, 데이터 특성과 도메인에 따라 분석가가 판단할 필요가 있음)
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# 데이터 준비
scaled_df = ...
# k 값 범위 설정
k_range = range(1, 11)
inertia = []
# 각 k 값에 대해 k-means 알고리즘 적용 및 Inertia 계산
for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=123)
kmeans.fit(scaled_df)
inertia.append(kmeans.inertia_)
# Inertia 값 시각화
plt.figure(figsize=(10, 6))
plt.plot(k_range, inertia, 'bo-')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia (WCSS)')
plt.title('Elbow Method for Optimal k')
plt.show()
Elbow Point 선택
- 그래프에서 Inertia가 급격히 감소하다가 완만해지는 지점이 Elbow Point입니다.
- 이 지점이 최적의 k 값으로 선택됩니다.
클러스터링 결과 해석하기
클러스터링 결과 해석 과정
- 모델 학습: KMeans 모델을 사용해 데이터를 k개의 클러스터로 나눕니다.
- 예측 추가: 학습된 모델을 통해 각 데이터 포인트가 어느 클러스터에 속하는지 예측하여, 원본 데이터프레임에 'label' 컬럼으로 추가합니다.
- 시각화: 특정 기준에 따라 클러스터를 시각화하고 클러스터별로 그룹을 형성하거나 하여 결과를 해석할 수 있습니다.
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
import seaborn as sns
import matplotlib.pyplot as plt
# 가상의 고객 데이터프레임 생성
data = {
'customer_id': range(1, 101),
'total_buy_cnt': np.random.poisson(10, 100),
'total_price': np.random.normal(500, 100, 100)
}
sales_df = pd.DataFrame(data)
# 데이터 스케일링
scaler = StandardScaler()
scaled_df = scaler.fit_transform(sales_df[['total_buy_cnt', 'total_price']])
# k-means 모델 학습
model = KMeans(n_clusters=3, random_state=123)
model.fit(scaled_df)
# 예측 결과를 원본 데이터프레임에 label 필드로 추가
sales_df['label'] = model.predict(scaled_df)
# 클러스터링 결과 시각화
plt.figure(figsize=(10, 6))
sns.scatterplot(x=sales_df['total_buy_cnt'], y=sales_df['total_price'], hue=sales_df['label'], s=100, palette='bright')
plt.title('Cluster Visualization')
plt.xlabel('Total Buy Count')
plt.ylabel('Total Price')
plt.show()
# 각 클러스터에 속한 고객 수 확인
cluster_counts = sales_df['label'].value_counts()
print("Cluster counts:\n", cluster_counts)
# 클러스터별 구매 행동 특징
groupby_df = sales_df.groupby('label').mean()
# 평균 개당 가격(price_mean) 컬럼 추가
groupby_df['price_mean'] = groupby_df['total_price'] / groupby_df['total_buy_cnt']
print("Cluster characteristics:\n", groupby_df)
# 클러스터별 맞춤 전략 요약
strategy_summary = {
0: "고객에게 구매 빈도에 따라 할인을 제공",
1: "비싼 제품 구매 고객을 위한 프리미엄 서비스 제공",
2: "중간 가격대 제품을 선호하는 고객을 위한 특별 이벤트"
}
print("Strategy summary:\n", strategy_summary)
Silhouette Coefficient
Silhouette Coefficient는 클러스터링의 품질을 평가하는 데 사용되는 지표이며, 개별 데이터가 할당된 군집 내 데이터와 얼마나 가깝게 군집화되어 있는지, 그리고 다른 군집에 있는 데이터와는 얼마나 멀리 분리되어 있는지를 표현한 수치입니다.
즉, 이 지표는 각 데이터 포인트가 적절하게 클러스터에 속해 있는지와 다른 클러스터와 얼마나 잘 분리되어 있는지를 측정합니다.
정의
Silhouette Coefficient는 다음과 같은 방식으로 계산됩니다:
- s(i): 개별 포인트의 실루엣 점수
- a(i): 동일 클러스터 내 다른 포인트들과의 평균 거리.
- b(i): 가장 가까운 다른 클러스터 내 포인트들과의 평균 거리(타 클러스터 점들과의 평균거리 중 최솟값).
값의 범위는 -1에서 1 사이이며, 값이 클수록 클러스터링 품질이 좋음을 나타냅니다.
- 1: 해당 데이터 포인트가 잘 클러스터링된 것.
- 0: 데이터 포인트가 두 클러스터 경계에 위치한 것.
- -1: 데이터 포인트가 잘못 클러스터링된 것.
활용
Silhouette Coefficient는 다음과 같은 방식으로 활용됩니다:
- -1에서 1 사이의 값을 가지며, 값이 클수록 클러스터링이 잘 되어 있음을 나타냅니다.
- Silhouette Score 전체 평균을 통해 최적의 클러스터 수를 판단할 수 있습니다.
Silhouette 분석을 통해 최적의 클러스터 수를 결정하며, 클러스터 개수에 따른 Silhouette Score를 비교하고 가장 높은 평균 Silhouette Score를 가진 클러스터 개수를 선택합니다.
K-means의 장점과 단점
장점
- 단순성과 효율성: 알고리즘이 간단하고, 대규모 데이터 세트에서도 빠르게 작동합니다. 변수들에 대한 배경지식이나 역할, 영향도를 모르더라도 데이터 사이의 거리만 구할 수 있다면 쉽게 사용할 수 있습니다.
- 수렴성: 대부분의 경우, 알고리즘은 빠르게 수렴하여 결과를 제공합니다. 이는 학습시간이 짧다는 장점으로 연결됩니다.
- 확장성: 큰 데이터 세트에서도 효율적으로 확장 가능합니다.
- 실용성: 많은 실제 응용 분야에서 널리 사용되며, 비교적 이해하기 쉽습니다. 또한, 알고리즘이 비교적 쉬운 수식으로 이루어졌기 때문에 이해와 해석이 용이합니다.
- k-means++ 초기화: K-Means++를 사용하면 초기 중심점(Centroid)을 좀 더 좋은 위치에 배치하여 일반 K-Means보다 안정적으로 클러스터링을 수행할 수 있습니다.
단점
- 초기화 중심점 위치에 민감: 초기 클러스터 중심의 선택이 최종 결과에 큰 영향을 미칠 수 있으며, 잘못된 초기화는 성능을 저하시킬 수 있습니다. 적절하지 않은 곳에 배치되면 연산 시간이 오래 걸릴 수 있고, 경우에 따라서는 수렴하지 못하는 경우도 발생할 수 있습니다.
- 클러스터 수 사전 지정 필요: 적절한 클러스터 개수 k를 미리 알아야 하는데, 이는 많은 경우 어려운 문제입니다. Elbow Method 등으로 단서를 얻을 수 있지만, 이는 합리적인 추론을 위한 가이드일 뿐 정답은 아닙니다.
- 클러스터가 구형임을 가정: K-Means는 클러스터가 구형이라고 가정하여, 비구형 클러스터에서는 성능이 저하될 수 있습니다.
- 노이즈 및 이상치에 민감: 잡음과 이상치에 민감하여, 클러스터링 결과가 왜곡될 수 있습니다. 이상치가 포함된 데이터일 경우 클러스터의 중심을 업데이트하는 과정에서 중심점의 위치가 크게 변동될 수 있습니다.
- 클러스터 간 사이즈가 다를 경우: 클러스터 크기가 다를 때, 작은 클러스터를 큰 클러스터의 일부로 잘못 분류할 수 있습니다.
- 클러스터 간 밀도가 다른 경우: 클러스터 밀도가 다르면, 밀도가 높은 클러스터와 낮은 클러스터를 잘못 분류할 수 있습니다.
- 차원이 높은 데이터에 대한 성능 저하: 차원이 높은 데이터에 적용할 때 성능이 떨어지는 단점이 있습니다.
k-means++ 사용법
from sklearn.cluster import KMeans
model = KMeans(n_clusters=k, init='k-means++')
K-Means++는 초기 중심점이 좀 더 좋은 위치에 잘 배치되도록 하여 일반 K-Means보다 안정적으로 클러스터링을 수행할 수 있게 해줍니다.
이번 글에서는 클러스터링 / K-Means 기초 / 모델과 학습 / Elbow Method / 클러스터링 결과 해석 / Silhouette Coefficient / K-Means의 장,단점이 포함된 내용을 정리했으며, 파이썬에서 데이터 분석을 하거나 프로그래밍을 하는 사람들에게 알아두면 유용한 개념들로 이번 기회를 통해 다른 분들도 정리하면 좋을 것 같습니다.
글 읽어주셔서 감사합니다.
출처 및 참고자료 : 코드잇 사이트 강의 '클러스터 분석' https://www.codeit.kr/topics/cluster-analysis
'프로그래밍 > 데이터 분석' 카테고리의 다른 글
[데이터 분석 심화 개념] 차원 축소 개념 정리 (0) | 2024.08.04 |
---|---|
[데이터 분석 심화 개념] 클러스터링 개념 정리 3️⃣ (다양한 클러스터링 모델) (0) | 2024.08.04 |
[데이터 분석 심화 개념] 클러스터링 개념 정리 1️⃣ (지도학습 및 비지도학습, 클러스터링) (0) | 2024.08.04 |
[Tableau 개념 정리] Tableau 기초 개념 정리 2️⃣ (3) | 2024.07.15 |
[Tableau 개념 정리] Tableau 기초 개념 정리 1️⃣ (0) | 2024.07.14 |
데이터 분석을 공부하고 카페를 열심히 돌아다니는 이야기
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!