now is better than never

7. [비지도학습] 군집분석 (Clustering) 본문

머신러닝 & 딥러닝

7. [비지도학습] 군집분석 (Clustering)

김초송 2023. 4. 3. 15:12

군집분석

  • 주어진 각 객체들의 유사성을 분석해 유사성이 높은 대상끼리 일반화된 그룹으로 분류
  • 데이터와 데이터 사이의 거리를 계산해서 가장 가까운 거리에 있는 데이터끼리 묶어줌
  1. 암판별 머신러닝 : 지도학습과 비지도학습을 같이 사용해서 모델의 정확도를 높임
  2. 마케팅 세그멘테이션 (segmentation)
  3. 보험사 맞춤형 보험상품 개발 및 광고
  4. 텔레콤 기지국 위치 선정

 

유클리드 거리

  • 군집분석에서 데이터 거리를 계산할 때 사용하는 수학식
  • 군집분석의 척도
    2차원 공간에서의 피타고라스 정리로 측정
    L2 거리

 

K-Means Clustering

  • 주어진 데이터를 K 개의 클러스터로 분할 군집하는 알고리즘
  • 각 클러스터간의 거리 차이의 분산을 최소화하는 군집분석 
  • 분석 전에 군집의 수를 정해놓고 군집의 중심으로 부터 가까운 순으로 군집에 들어갈 데이터를 정하는 방법
  • 장점 
    1. 다양한 데이터 형태에 적용 가능
    2. 특정 변수에 대한 정의가 필요하지 않는 적용이 용이함
  • 단점
    1. 초기 군집수 (k 값) 에 따라 결과가 바뀔 수 있음
    2. 이상치에 민감
      ->  이상치를 제거하거나
           이상치를 둔감하게 만듦 = 정규화
  • 정규화
    : 데이터로부터 잡음(이상치)를 제거하기 위해 데이터 추세를 벗어나는 값들을 변화하는 기법
  • 표준화
    : 데이터를 0을 중심으로 양쪽으로 데이터를 분포시키는 방법

 

R 로 K-means 모델 구현

  1. 데이터 로드
  2. 분류에 필요한 컬럼만 선택
  3. 비지도학습으로 2개로 군집화
  4. 시각화
  5. 모델 평가

  6. 데이터 정규화
  7. 군집화
  8. 시각화
  9. 모델 평가
wisc <- read.csv("C:/Data/wisc_bc_data.csv")

install.packages("factoextra")
library(factoextra)

# 2개로 군집화
km <- kmeans(wisc[, 3:32], 2) # 환자번호, 정답컬럼 제외
km

fviz_cluster(km, data=wisc[, 3:32], stand=F)

cbind(wisc$id, wisc$diagnosis, km$cluster) #각각의 좌표가 어느 군집인지 출력
library(gmodels)
CrossTable(wisc$diagnosis, km$cluster) # 정확도 0.85

# 데이터 정규화 후 정확도
normalize <- function(x){ return (x - min(x)) / (max(X) - min(x)) }
wisc2 <- as.data.frame(lapply(wisc[ , 3:32], normalize))
wisc2

km2 <- kmeans(wisc2, 2)

library(factoextra)
fviz_cluster(km2, data=wisc2, stand=F)

cbind(wisc$id, wisc$diagnosis, km2$cluster)
library(gmodels)
CrossTable(wisc$diagnosis, km2$cluster)
# 0.92 로 증가

 

Python 으로 K-means 모델 구현

  1. 데이터 로드
  2. 결측치 확인
  3. 필요한 컬럼 선택
  4. 정규화 진행
  5. 모델 생성
  6. 모델 훈련
  7. 군집 결과 확인
  8. 정확도 확인 <- 비지도 학습은 원래 정확도 확인 안 함
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans

df = pd.read_csv("C:/Data/wisc_bc_data.csv")
df.head()

df.isnull().sum()

df2 = df.iloc[ : , 2: ] # 환자 번호와 정답 제외
df2.head()

scaler = MinMaxScaler()
scaler.fit(df2)
df_scaled = scaler.transform(df2)
df_scaled

model = KMeans(n_clusters=2, random_state=1)
model.fit(df_scaled)
km = model.labels_
km # 0 이 양성인지 악성인지 알 수 없음

df['cluster'] = km
df[['diagnosis', 'cluster']]

# ---------------------------------

y_train = df.diagnosis.apply(lambda x:x=='M').astype(int)
y_train

from sklearn.metrics import confusion_matrix
confusion_matrix(y_train, df.cluster) # 정답, 예측값
# 정확도 0.92
본 내용은 아이티윌 '빅데이터&머신러닝 전문가 양성 과정' 을 수강하며 작성한 내용입니다.