728x90
SMALL

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

군집 분석

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

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

 

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

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

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

피처 선정

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

이 과정을 피처(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 같은 군집 알고리즘 비교와 알고리즘을 평가하는 방법에 대해 포스팅하도록 하겠습니다1

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

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

728x90
LIST

+ Recent posts