728x90
SMALL

안녕하세요! 오늘은 기존에 작성했던 군집 분석을 이어서 포스팅 하겠습니다.

군집 분석

군집 분석은 정답(라벨)이 없는 데이터를 비슷한 특성끼리 그룹으로 나누는 비지도 학습 방법입니다.
고객을 세분화하거나, 이상치를 탐지할 때 유용하게 쓰이는 분석 방법입니다!
 
군집 분석은 크게 아래 4가지 과정을 거쳐 진행되는데요.

  1. 피처 선정
  2. 차원 축소
  3. 알고리즘 적용
  4. 알고리즘 평가

오늘은 알고리즘 적용과 알고리즘 평가에 대해서 설명 드리겠습니다:)

피처 선정과 차원 축소에 대한 설명은 아래 포스팅에서 진행하고 있으니, 먼저 확인해주세요!

https://yhj9855.com/entry/ML-%EA%B5%B0%EC%A7%91-%EB%B6%84%EC%84%9D-1

 

[ML] 군집 분석 - 1

안녕하세요! 오늘은 머신 러닝의 비지도 학습 내 대표 알고리즘, 군집 분석에 대해 포스팅 하겠습니다.군집 분석군집 분석은 정답(라벨)이 없는 데이터를 비슷한 특성끼리 그룹으로 나누는 비지

yhj9855.com

알고리즘 적용

군집 분석은 아래의 총 4가지 알고리즘을 가장 많이 사용합니다!

  1. KMeans
  2. Mean Shift
  3. GMM
  4. DBSCAN
  • KMeans

가장 대표적인 군집화 방법입니다!

미리 군집 수(K)를 정해두고, 각 데이터를 가장 가까운 중심점으로 할당합니다.

 

빠르고 간단하지만, 군집 수를 미리 사전에 알아야 하는데요.

이 때, 적절한 군집 수를 판단하는 방법이 바로 엘보우 방법입니다.

  • 엘보우 방법

KMeans에서 군집 수를 정할 때, 적절한 K를 찾기 위한 시각적 기법입니다!

엘보우 원리는 아래와 같습니다.

  1. K를 1부터 시작해서 점차 늘려가며 KMeans 실행
  2. 각 K의 군집 내 거리의 합을 계산
  3. K가 커질수록 합이 작아지지만, 어느 순간 완만하게 떨어지는 지점이 나타남
  4. 그 지점을 엘보우라고 부르며, K값이 적절한 군집이라고 판단

엘보우 방법의 코드는 아래와 같습니다.

# kmeans 군집을 결정하기 위한 엘보우 방법
a = []
for k in range(2, 7) :
    kmeans = KMeans(n_clusters=k,init='k-means++', max_iter=300, random_state=42)
    # df_scaled는 정제된 데이터
    kmeans.fit_predict(df_scaled)
    a.append(kmeans.inertia_)
plt.plot(range(2,7), a)
plt.show()

코드를 실행해서, 위와 같은 결과물을 얻을 수 있었는데요!

3인 구간에서 완만하게 꺾이기 때문에, 제가 가진 데이터의 적절한 군집은 3이라는 것을 알 수 있습니다.

 

엘보우 방법으로 적절한 K를 구했다면, KMeans를 바로 실행할 수 있습니다.

KMeans를 실행하는 코드는 아래와 같습니다.

# 엘보우를 통해서 3개의 군집 적용
kmeans = KMeans(n_clusters=3,init='k-means++', max_iter=300, random_state=42
# df_tsne는 차원 축소까지 끝난 데이터
k_clusters = kmeans.fit_predict(df_tsne)

# 군집 시각화
plt.figure(figsize=(8, 6))
sns.scatterplot(x=df_tsne[:, 0], y=df_tsne[:, 1], hue=k_clusters, palette='viridis', s=100)
plt.show()

KMeans 알고리즘을 통해 군집이 잘 분류된 것을 보실 수 있습니다:)

728x90
  • Mean Shift

군집을 자동으로 결정해주는 알고리즘으로, 데이터가 밀집된 방향으로 중심을 이동시키며 군집을 형성합니다.

군집을 미리 알 필요는 없지만, 계산량이 많고 고차원 데이터는 부적합한 경향이 있습니다!

요즘은 차원 축소도 많이 하고, 컴퓨터가 좋아서 계산량이 많아 느리다는 체감은 잘 못했어요.

 

Mean Shift를 실행하는 코드는 아래와 같습니다.

mean_shift = MeanShift()
mean_clusters = mean_shift.fit_predict(df_tsne)

# 군집 시각화
plt.figure(figsize=(8, 6))
sns.scatterplot(x=df_tsne[:, 0], y=df_tsne[:, 1], hue=mean_clusters, palette='viridis', s=100)
plt.title('MeanShift Clustering with t-SNE')
plt.show()

Mean Shift 알고리즘을 통해 군집이 잘 분류된 것을 보실 수 있습니다:)

  • GMM

Gaussian Mixture Model의 줄임말로, 군집을 확률적으로 나누는 방법입니다!

각 데이터가 군집에 속할 확률을 기반으로 군집 분류하기 때문에 비대칭이나 겹치는 군집도 처리가 가능합니다.

하지만, 복잡도가 높고 잘못된 초기값에 민감한 단점이 있습니다.

GMM도 군집 설정을 해줘야 하기 때문에 엘보우 방법으로 찾은 군집을 같이 적용하는 것이 좋습니다.

 

GMM를 실행하는 코드는 아래와 같습니다.

gmm = GaussianMixture(n_components=3)
gmm.fit(df_tsne)
gmm_clusters = gmm.predict(df_tsne)

# 군집 시각화
plt.figure(figsize=(8, 6))
sns.scatterplot(x=df_tsne[:, 0], y=df_tsne[:, 1], hue=gmm_clusters, palette='viridis', s=100)
plt.title('GMM Clustering with t-SNE')
plt.show()

GMM 알고리즘을 통해 군집이 잘 분류된 것을 보실 수 있습니다:)

  • DBSCAN

밀도가 높은 지역을 하나의 군집으로 간주하여, 이웃 점의 수가 일정 기준 이상이면 같은 군집으로 묶는 방법입니다!

이상치 탐지에 강하고, 모양이 복잡한 군집을 잘 나누는 편이라 복잡한 데이터에 잘 어울리는 알고리즘이에요.

다만, 하이퍼파라미터에 민감하고, 밀도 차이가 크거나 단순한 데이터에는 오히려 부적합할 수 있습니다.

 

DBSCAN를 실행하는 코드는 아래와 같습니다.

dbscan = DBSCAN(eps=3, min_samples=2)
dbscan_clusters = dbscan.fit_predict(df_tsne)

# 군집 시각화
plt.figure(figsize=(8, 6))
sns.scatterplot(x=df_tsne[:, 0], y=df_tsne[:, 1], hue=dbscan_clusters, palette='viridis', s=100)
plt.title('DBSCAN Clustering with t-SNE')
plt.show()

 

DBSCAN 알고리즘을 통해 군집이 잘 분류된 것을 보실 수 있습니다:)

다만 같은 데이터로도, DBSCAN은 너무 세부적으로 분류하여 군집이 많이 생성된 것을 보실 수 있습니다!

SMALL

알고리즘 평가

알고리즘을 적용했으면, 어떤 알고리즘이 잘 적용이 된 것인지 확인할 필요가 있습니다.

이 때 사용하는 것이 바로 실루엣 점수입니다.

  • 실루엣 점수

실루엣 점수는 각 데이터가 자기 군집 안에서는 얼마나 가까이 있고, 다른 군집과는 얼마나 멀리 떨어져 있는지를 수치로 나타낸 지표입니다.

값의 범위는 -1에서 1사이로, 1에 가까울수록 군집이 잘 분리된 것인데요.

일반적으로는 0.5를 넘으면 군집이 잘 만들어진 것이고, 0.25미만이면 잘 안된 것이라고 판단합니다.

 

실루엣 점수를 확인하는 코드는 아래와 같습니다.

# k_clusters는 KMeans 군집 분석 결과
silhouette_avg = silhouette_score(df_tsne, k_clusters)

# mean_clusters는 Mean Shift 군집 분석 결과
silhouette_avg = silhouette_score(df_tsne, mean_clusters)

# gmm_clusters는 GMM 군집 분석 결과
silhouette_avg = silhouette_score(df_tsne, gmm_clusters)

# dbscan_clusters는 DBSCAN 군집 분석 결과
silhouette_avg = silhouette_score(df_tsne, dbscan_clusters)

 

저는 실루엣 점수를 확인해보니, KMeans, Mean Shift, GMM 모두 동일하게 0.76이 나왔고, DBSCAN만 0.47이 나왔습니다.

군집이 많이 분류되는 것이 꼭 좋은 모델은 아니라는 점!

 

여기까지 군집 분석에 관한 내용이었습니다:D

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

728x90
LIST

'Python(파이썬) > ML(머신 러닝)' 카테고리의 다른 글

[ML] 군집 분석 - 1  (0) 2025.07.13
728x90
SMALL

 

 

 

 

 

안녕하세요! 오늘은 머신 러닝의 비지도 학습 내 대표 알고리즘, 군집 분석에 대해 포스팅 하겠습니다.

군집 분석

군집 분석은 정답(라벨)이 없는 데이터비슷한 특성끼리 그룹으로 나누는 비지도 학습 방법입니다.

고객을 세분화하거나, 이상치를 탐지할 때 유용하게 쓰이는 분석 방법입니다!

 

군집 분석은 크게 아래 4가지 과정을 거쳐 진행되는데요.

  1. 피처 선정
  2. 차원 축소
  3. 알고리즘 적용
  4. 알고리즘 평가

오늘은 피처 선정과 차원 축소에 대해서 설명 드리겠습니다:)

 

알고리즘 적용과 평가에 대해 궁금하신 분들은 아래 링크를 확인해주세요!

https://yhj9855.com/entry/ML-%EA%B5%B0%EC%A7%91-%EB%B6%84%EC%84%9D-2

 

[ML] 군집 분석 - 2

안녕하세요! 오늘은 기존에 작성했던 군집 분석을 이어서 포스팅 하겠습니다.군집 분석군집 분석은 정답(라벨)이 없는 데이터를 비슷한 특성끼리 그룹으로 나누는 비지도 학습 방법입니다.고객

yhj9855.com

피처 선정

비슷한 특성을 그룹으로 나누기 때문에 그룹으로 나누고자 하는 좋은 특정을 골라주는 작업이 정말 중요한데요!

이 과정을 피처(Feature) 선정이라고 합니다.

 

피처각 데이터를 설명해주는 변수들로, 고객 데이터에서 나이, 연봉, 방문 횟수 같은 것을 의미합니다.

불필요한 피처는 군집을 흐리게 만들거나, 의도하지 않은 방향으로 군집을 만들기도 합니다.

또한, 중복된 피처 정보는 모델에 부담을 주기도 하기 때문에 불필요한 피처를 버리는 과정이 정말 중요해요!

  • 피처 선정 기준

피처를 선정할 때는 보통 아래 3가지 방법을 사용합니다.

  1. 분산 기반 (Variance)
  2. 상관 계수 기반 (Correlation)
  3. 정보 이득 기반 (Information Gain)
  • 분산 기반 (Variance)

분산피처가 얼마나 많은 변동성을 가지는지를 나타내기 때문에, 변동성이 거의 없는 피처는 군집에 영향이 없다고 볼 수 있어요!

분산이 거의 없는 피처를 제거함으로써 모델에 부담을 줄이고, 조금 더 명확한 군집을 생성할 수 있도록 할 수 있습니다.

 

일반적으로는 0.01 이하 피처는 거의 변동이 없다고 생각할 수 있습니다.

전체 피처 중 하위 5% 또는 10%에 해당하는 분산을 가진 피처를 제거하는 방법도 있기 때문에, 분산 조절은 상황에 맞게 하시면 됩니다:)

 

0.01 이하의 분산을 제거하는 코드는 아래와 같습니다.

# VarianceThreshold 적용
selector = VarianceThreshold(threshold=0.01)
# features: 피처가 들어있는 데이터 프레임
selector.fit(features)

# 선택된 피처의 인덱스와 이름 추출
selected_features = features.columns[selector.get_support()]

# 제거된 피처 확인
#removed_features = data.columns[~selector.get_support()]

reduced_data = pd.DataFrame(selector.transform(features), columns=selected_features)

 

 

728x90
  • 상관 계수 기반 (Correlation)

상관 계수서로 얼마나 유사한지를 나타내기 때문에, 상관 계수가 높은 피처들은 서로 중복된 정보라고 볼 수 있어요!

상관 계수가 높은 피처 중 하나를 제거하여 중복성을 줄이고, 모델에 부담을 줄일 수 있습니다.

 

상관 계수를 계산하고, 제거하는 코드는 아래와 같습니다.

저는 csv 파일로 만들어서 제거하는게, 더 빨라서 그렇게 했어요ㅎㅎ

# 상관 행렬 계산
corr_matrix = reduced_data.corr().abs()

# 상관 계수가 높은 피처 중복 제거
upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool))

# csv 파일을 통해 확인하고 직접 제거
upper.to_csv('상관 계수.csv')
  • 정보 이득 기반 (Information Gain)

정보 이득서로 상호 의존성을 측정하는 방법으로, 값이 높을수록 해당 피처가 다른 피처들과 유의미한 상호작용을 갖는다는 것을 의미합니다.

유의미하지 못한 피처들을 제거하여 조금 더 명확한 군집을 생성할 수 있어요!

 

일반적으로 0.3 이상의 값을 가져야, 중요도가 높다고 해석할 수 있습니다.

0.1 미만의 값은 거의 기여하지 않는다고 볼 수 있고, 그 사이 값들은 중요도가 낮다고 볼 수 있어요.

어느 점수에서 피처를 제거할지는 상황에 맞게 하시면 됩니다:)

 

kmeans 알고리즘 적용 후, 정보 이득 점수에 따라 피처를 제거하는 코드는 아래와 같습니다!

kmeans 알고리즘 외 다른 군집 분석 알고리즘을 사용하셔도 좋습니다ദ്ദിㆁᴗㆁ✿)

# KMeans를 위한 데이터 정제
#  데이터 정규화 또는 표준화
scaler = StandardScaler()
df_scaled = scaler.fit_transform(data)

# KMeans 적용
kmeans = KMeans(n_clusters=3,init='k-means++', max_iter=300, random_state=42)
clusters = kmeans.fit_predict(df_scaled)

# 피처 이름과 중요도를 함께 저장
feature_importance_df = pd.DataFrame({
    'Feature': data.columns,
    'Importance': mi_scores
})

# 중요도에 따라 정렬
# 해당 값을 직접 확인해서 컬럼 제거
feature_importance_df = feature_importance_df.sort_values(by='Importance', ascending=False)

 

 

SMALL

차원 축소

데이터에서 차원은 피처의 개수를 의미하는데, 차원이 높을수록 여러 가지 문제가 발생합니다ㅠㅠ

대표적으로는 계산량이 증가되고, 알고리즘 성능이 떨어지며, 시각화가 어렵다는 문제가 있는데요!

이를 방지하기 하기 위해 원래 데이터의 주요 정보를 최대한 보존하면서 변수(차원)의 수를 줄이는 방법을 차원 축소하고 합니다.

 

차원 축소의 대표적인 알고리즘은 PCA와 t-SNE가 있는데, 요즘은 t-SNE를 더 자주 사용한다고 하네요:)

차원 축소를 할 때는 어떤 차원으로 축소 가능하지만, 보통 시각화를 위해서 2차원이나 3차원으로 축소를 합니다!

그리고 차원 축소가 불필요한 중복을 추가로 제거해주기 때문에, 알고리즘 적용 전에 하시는게 더 좋습니다.

 

t-SNE 알고리즘으로 2차원 축소하는 코드는 아래와 같습니다.

코드 자체는 정말 단순하네요ㅋㅋㅋㅋ

# TSNE를 활용하여 차원 축소 진행
tsne = TSNE(n_components=2, random_state=42, perplexity=30)
df_tsne = tsne.fit_transform(df_scaled)

 

차원 축소를 하시고, 알고리즘을 적용하면 아래 처럼 수월하게 시각화를 진행할 수 있어요:D

 

여기까지가 군집 분석을 위한 피처 선정과 차원 축소에 관련된 내용이었습니다.

군집 분석은 불필요한 정보를 많이 포함할 수록 기능이 상당히 떨어지기 때문에 전처리하는 과정이 정말 중요합니다ㅠㅠ

저도 군집 분석하면서 전처리하는게 가장 힘들었어요...ㅎㅎ

 

KMeans, GMM 같은 군집 알고리즘 비교와 알고리즘을 평가하는 방법은 아래 링크를 확인해주세요!

https://yhj9855.com/entry/ML-%EA%B5%B0%EC%A7%91-%EB%B6%84%EC%84%9D-2

 

[ML] 군집 분석 - 2

안녕하세요! 오늘은 기존에 작성했던 군집 분석을 이어서 포스팅 하겠습니다.군집 분석군집 분석은 정답(라벨)이 없는 데이터를 비슷한 특성끼리 그룹으로 나누는 비지도 학습 방법입니다.고객

yhj9855.com

궁금한 부분이 있으신 분들은 댓글로 남겨주시면, 답변 드리도록 하겠습니다.

★읽어주셔서 감사합니다★

 

 

 

 

 

728x90
LIST

'Python(파이썬) > ML(머신 러닝)' 카테고리의 다른 글

[ML] 군집 분석 - 2  (5) 2025.08.17

+ Recent posts