[3월 3주차-3/19]비지도 학습으로 댓글을 분석해보자! (KMeans 군집화)
데이터 분석에서 가장 중요한 것은 데이터를 잘 분류하고 이해하는 것입니다. 하지만 우리가 다루는 데이터는 대부분 정답(라벨)이 없는 경우가 많죠.
이런 경우, 비지도 학습(Unsupervised Learning) 기법을 활용하여 데이터를 자동으로 분류할 수 있습니다.
이번 포스팅에서는 **KMeans 군집화(Clustering)**를 사용하여 댓글 데이터를 분석하는 방법을 소개합니다.
🔍 1. 댓글 분석이 필요한 이유?
쇼핑몰, 커뮤니티, SNS 등에 달린 수천 개의 댓글을 사람이 일일이 읽고 분석하기는 어렵습니다.
하지만 군집화를 활용하면 비슷한 내용의 댓글을 자동으로 분류할 수 있습니다!
✅ 활용 예시
- 특정 제품에 대한 고객 관심도 분석
- 고객층을 나누어 타겟 마케팅 전략 수립
- 특정 키워드(예: "딥러닝", "자바스크립트")가 포함된 댓글만 찾아 트렌드 분석
그럼, 실제로 댓글 데이터를 수집하고 KMeans 군집화를 적용하는 과정을 살펴보겠습니다.
🔧 2. 데이터 전처리
군집화를 하기 전, 먼저 데이터를 정리(전처리) 해야 합니다.
① 데이터 불러오기 & 중복 제거
import pandas as pd
df = pd.read_csv('data/event_text.csv')
# 중복된 댓글 제거
df = df.drop_duplicates(['text'], keep='last')
같은 댓글이 여러 번 달렸다면 중복을 제거하는 과정입니다.
② 소문자로 변환
df['text'] = df['text'].str.lower()
"Python"과 "python"을 같은 단어로 인식하기 위해 소문자로統一합니다.
③ 같은 의미의 단어 통합
df['text'] = df['text'].str.replace('python', '파이썬').str.replace('pandas', '판다스')
"Python"과 "파이썬"을 같은 단어로 처리하기 위해 정리하는 과정입니다.
④ 특정 키워드 추출
search_keyword = ['머신러닝', '딥러닝', '파이썬', '자바', '자바스크립트']
for keyword in search_keyword:
df[keyword] = df['text'].str.contains(keyword)
댓글 속에서 특정 키워드(예: "파이썬")가 포함되어 있는지 T/F 값으로 표시합니다.
🔢 3. 텍스트 데이터를 숫자로 변환 (TF-IDF)
군집화를 적용하려면 텍스트 데이터를 숫자로 변환해야 합니다.
이를 위해 TF-IDF(Term Frequency - Inverse Document Frequency) 기법을 사용합니다.
from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer
vectorizer = CountVectorizer(min_df=2, max_features=2000, ngram_range=(3,6))
feature_vector = vectorizer.fit_transform(df['text'])
tfidftrans = TfidfTransformer(smooth_idf=False)
feature_tfidf = tfidftrans.fit_transform(feature_vector)
✅ TF-IDF란?
- 자주 등장하는 단어에는 가중치를 낮추고
- 특정 문서에서만 자주 등장하는 단어에는 가중치를 높이는 기법
✅ 왜 필요한가요?
- "자주 등장하는 흔한 단어"가 아니라 **"핵심적인 단어"**를 반영하기 위해서입니다.
🎯 4. KMeans 군집화 적용
이제 KMeans 군집화를 사용해서 댓글을 비슷한 그룹으로 묶어보겠습니다.
🔹 엘보우 방법 (적절한 K 값 찾기)
우리는 몇 개의 군집(K)으로 데이터를 나눠야 할까요?
이를 결정하는 대표적인 방법이 엘보우 방법(Elbow Method) 입니다.
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
inertia = []
start, end = 10, 70
for i in range(start, end):
kmeans = KMeans(n_clusters=i, random_state=42)
kmeans.fit(feature_tfidf)
inertia.append(kmeans.inertia_)
plt.plot(range(start, end), inertia)
plt.title('클러스터 수 비교')
plt.show()
✅ 엘보우 방법이란?
- X축: 군집(K)의 개수
- Y축: 군집 내부의 거리(inertia)
- 그래프가 급격히 꺾이는 지점이 최적의 K 값!
📊 5. 군집 분석 결과 시각화
🔹 실루엣 점수(Silhouette Score)
클러스터링의 품질을 평가하는 지표로 실루엣 점수를 사용합니다.
from sklearn.cluster import MiniBatchKMeans
from sklearn.metrics import silhouette_score
b_inertia = []
silhouettes = []
for i in range(start, end):
mkmeans = MiniBatchKMeans(n_clusters=i, random_state=42)
mkmeans.fit(feature_tfidf)
b_inertia.append(mkmeans.inertia_)
silhouettes.append(silhouette_score(feature_tfidf, mkmeans.labels_))
plt.plot(range(start, end), silhouettes)
plt.title('실루엣 점수 비교')
plt.show()
✅ 실루엣 점수가 높을수록 클러스터링이 잘된 것입니다!
🔍 6. 군집별 대표 키워드 분석
이제 각 군집에서 어떤 단어가 가장 많이 등장하는지 확인해보겠습니다.
labels = np.unique(prediction)
df_cluster_score = []
df_cluster = []
for label in labels:
id_temp = np.where(prediction==label)
x_means = np.mean(feature_array[id_temp], axis=0)
sorted_means = np.argsort(x_means)[::-1][:n_clusters]
features = vectorizer.get_feature_names_out()
best_features = [(features[i], x_means[i]) for i in sorted_means]
df_score = pd.DataFrame(best_features, columns=['features', 'score'])
df_cluster_score.append(df_score)
df_cluster.append(best_features[0])
pd.DataFrame(df_cluster, columns=['features', 'score']).sort_values(by=['features','score'], ascending=False)
✅ 이 과정은 각 군집에서 가장 중요한 단어(키워드)를 뽑아내는 과정입니다.
예를 들어,
- 1번 군집에서 "딥러닝", "머신러닝", "AI" 같은 단어가 많다면 → AI 관심 그룹
- 2번 군집에서 "자바스크립트", "리액트", "웹개발" 단어가 많다면 → 웹 개발 관심 그룹
🎯 7. 정리
✔ **군집화(Clustering)**는 정답(라벨)이 없는 데이터를 비슷한 그룹으로 묶는 방법입니다.
✔ 댓글 분석을 통해 고객의 관심사를 파악하고 마케팅 전략을 세울 수 있습니다.
✔ TF-IDF를 이용해 텍스트 데이터를 숫자로 변환하여 머신러닝 모델이 처리할 수 있도록 했습니다.
✔ KMeans 군집화를 사용하여 데이터를 자동으로 그룹화했습니다.
✔ 엘보우 방법과 실루엣 점수를 이용해 최적의 K 값을 찾았습니다.
✔ 군집별 키워드 분석을 통해 각 그룹의 특징을 확인했습니다.