계층 클러스터링 메모리 사건
우선 어제 계층 클러스터링 하다가 메모라가 다 터져서 튜터님 두 분께 여쭤봤을 때, 두 분 다 다른 대안 머신러닝이 있으면 굳이 쓸 필요 없다고 말씀하셨다.
그리고 DBSCAN 또한 KMeans보다 훨씬 덜 쓰이기 때문에, KMeans 위주로 하는 것을 추천하셨다.
원핫인코딩 ->라벨인코딩
튜터님께 지금까지 하는 게 잘 돼가고 있는지 확인해달라고 하며 코드들을 다 보여드렸는데, PCA 결과가 이상하다고 하셨다.
바로 이거...!
이렇게 각 데이터들이 점 형태로 보이지 않고 다 뭉쳐있으면 문제가 있는 거라고 하셨다.
Q. 컬럼수가 너무 많아서 그럴 가능성은 없나요?
A.네. 이러면 안돼요.
단호박 그 자체셨다.. 그래서 문제점을 보시다가, 인코딩에 문제가 있는 것 같다고 하셨다.
데이터 자체가 도메인이 많은 컬럼들이 아니기 때문에, 순서가 생긴다고 해서 큰 문제가 생기지 않는다고 하셨다.
X잘못된 예시
#원핫인코딩
one_hot =['country','category1','category2','payment_type']
df_customer = pd.get_dummies(df_customer, columns=one_hot)
#라벨인코딩
label = ['gender','marketing_info_agree']
encoder = LabelEncoder()
for col in label:
df_customer[col] = encoder.fit_transform(df_customer[col])
O 수정된 버전
label = ['gender','marketing_info_agree','country','category1','category2','payment_type'] #'country','category1','category2','payment_type'추가
encoder = LabelEncoder()
for col in label:
df_customer[col] = encoder.fit_transform(df_customer[col])
모든 범주형 데이터를 라벨 인코딩으로 바꿨다.
군집에는 우선 연속형만 넣고, 범주형은 하나씩 넣기
범주형 때문에 결과가 확확 달라지기 때문에 하나씩 넣어서 어떤 컬럼이 문제가 있는지를 잘 봐야한다.
그래서 아까 집계한 컬럼 중 연속형만 따로 모았다.
df_customer_info = df_customer[['payment_installments','shipping_charges','volume_cm3','weight_kg','price','delivery_delay_days','review_score','approval_delay_minutes','age']]
PCA, KMenas/ DBSCAN 결과
pca 결과 / 2차원
pca 결과 / 3차원
KMeans 결과/ 2차원
KMeans결과 /3차원
DBSCAN 결과 /2차원
DBSCAN 결과 /3차원
왜 현업에서는 KMeans를 쓰는지 알 것 같았다.
KMenas는 각각 데이터의 중심을 찾아서 뭉쳐지는 반면, DBSCAN은 얼마나 떨어져있는지를 보고 데이터끼리 뭉치는 거기 때문에 일반적으로는 KMeans가 나을 것 같다.
인코딩한 범주형 컬럼들 하나씩 넣어보며 이상 있는지 확인
# 서브플롯 설정
fig, ax = plt.subplots(2, 3, figsize=(18, 10))
ax = ax.flatten()
for i, col in enumerate(label):
# 수치형 + 현재 컬럼만 합친 데이터
df_temp = pd.concat([df_customer_info, df_customer[[col]]], axis=1)
# PCA
pca = PCA(n_components=2, svd_solver='full', random_state=42)
pca_result = pca.fit_transform(df_temp)
pca_df = pd.DataFrame(pca_result, columns=['PC1', 'PC2'])
# scatter plot
ax[i].scatter(
pca_df['PC1'],
pca_df['PC2'],
)
ax[i].set_title(f'PCA by {col}\nExplained Var: {pca.explained_variance_ratio_.sum():.2f}', fontsize=12)
ax[i].set_xlabel('PC1')
ax[i].set_ylabel('PC2')
ax[i].grid(True)
# 전체 타이틀 & 레이아웃 조정
plt.suptitle('PCA 2D Scatter Plots by Each Label Feature', fontsize=16)
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()
누가봐도 country랑 카테고리2가 문제 있는 것 처럼 보인다. 딱 각 값에 따라서만 나뉘는 걸로 보인다.
군집별 비중
k값이 뭐든, 한 군집의 비중은 50%가 넘으면 안된다. 그래서 비중 구하는 코드를 따로 추가해주기로 한다.
# 클러스터 개수 목록
ks = [8]
# 그래프 크기 설정
plt.figure(figsize=(18, 5))
for i, k in enumerate(ks):
# KMeans 모델 생성 및 학습
kmeans = KMeans(n_clusters=k, random_state=42,n_init=10)
labels = kmeans.fit_predict(pca2_df)
# 라벨 컬럼 붙이기
kmeans_df = pd.concat([pca2_df, pd.DataFrame({'Cluster': labels})], axis=1)
# 3) 비율 계산
props = kmeans_df['Cluster'].value_counts(normalize=True).sort_index() * 100
# 콘솔에 출력
print(f"k = {k}일 때 클러스터 비율 (%)")
for cluster_id, pct in props.items():
print(f" Cluster {cluster_id}: {pct:.2f}%")
print()
# subplot 지정
plt.subplot(1, 3, i+1)
sns.scatterplot(data=kmeans_df, x='PC1', y='PC2', hue='Cluster', palette='Set3')
plt.title(f'KMeans Clustering (k = {k})')
plt.xlabel('PC1')
plt.ylabel('PC2')
plt.legend(title='Cluster')
#kmeans_sil = silhouette_score(pca2_df, labels)
#print(f"K-Means: 실루엣 점수 = {kmeans_sil:.4f} | 클러스터 개수 = {k}")
plt.tight_layout()
plt.show()
그럼 이렇게 예쁘게 잘 나온다!
우리팀의 실험 방식
이렇게 구글 스프레드시트에 작업자명, k값, 사용 컬럼, 주성분 개수, plot, 레이더차트, 군집별 비중 등을 넣어서 실험해보기로 했다!
'데이터분석 6기 > 본캠프' 카테고리의 다른 글
2025-04-25 군집 분석 (0) | 2025.04.25 |
---|---|
2025-04-25 심화 프로젝트 군집 실험 시작 (1) | 2025.04.24 |
2025-04-22 심화 프로젝트 - 군집(PCA, KMeans, DBSCAN) (1) | 2025.04.22 |
2025-04-21 심화 프로젝트 EDA 2 (0) | 2025.04.21 |
2025-04-18 심화 프로젝트 EDA (0) | 2025.04.19 |