[KT AIVLE] DX트랙 머신러닝(7주차) 복습(비지도학습: 차원 축소, 클러스터링)

728x90

머신러닝 복습

비지도학습

  • 레이블이나 명시적인 결과 없이 입력 데이터의 구조나 패턴을 발견하고 모델링하는 방법

비지도 학습만으로 끝나지 않고 후속 작업 필요

  • 차원 축소: 고차원 데이터를 축소하여 새로운 feature 생성
  • Clustering: 고객별 군집 생성
  • 이상탐지: 정상 데이터 범위 지정

 

1. 차원 축소

  • 고차원 데이터는 많은 특성(feature)을 가지고 있기 때문에 데이터를 시각화하거나 분석하기 어려움
  • 또한, 차원이 증가함에 따라 데이터의 복잡성도 증가  학습 알고리즘의 성능이 저하됨(차원의 저주)
  • 따라서 차원 축소 데이터의 복잡성을 줄이고 효율적인 분석을 가능하게 함
  • ex) 주성분 분석(PCA), t-SNE

 

주성분 분석(PCA)

  • 데이터를 새로운 축으로 변환하여 가장 많은 분산을 보존하는 주성분을 찾아내는 방법
  • 스케일링 필요
  • PCA 절차
    1. 학습 데이터셋에서 분산이 최대 첫번째 축(axis)을 찾음.
    2. 첫번째 축과 직교(orthogonal)하면서 분산이 최대 두 번째 축을 찾음.
    3. 첫 번째 축과 두 번째 축에 직교하고 분산이 최대 세 번째 축을 찾음.
    4. ①~③과 같은 방법으로 데이터셋의 차원 만큼의 축을 찾음.
# 주성분 분석 선언

# 주성분 1개짜리
pca1 = PCA(n_components=1)
x_pc1 = pca1.fit_transform(x_train)

# 주성분 2개짜리
pca2 = PCA(n_components=2)
x_pc2= pca2.fit_transform(x_train)

# 주성분 3개짜리
pca3 = PCA(n_components=3)
x_pc3= pca3.fit_transform(x_train)

# 각 주성분 결과 상위 3개 확인
print(x_pc1[:3])
print('-'*50)
print(x_pc2[:3])
print('-'*50)
print(x_pc3[:3])

주성분 결과 상위 3개

주성분의 개수 정하기

# 주성분 개수에 따른 주성분의 설명된 분산 비율 시각화
plt.plot(range(1,n+1), pca.explained_variance_ratio_, marker = '.')
plt.xlabel('No. of PC')
plt.grid()
plt.show()
  • .explained_variance_ratio_: 각 주성분이 설명하는 분산의 비율

Elbow Method

주성분 개수에 따른 시각화 / 엘보우 메소드

 

2. 클러스터링

  • Cluster를 서로 유사한 그룹으로 분할하는 과정
  • ex) K-Means, DBSCAN

K-Means

  • K개의 평균으로 부터 거리를 계산하고, 가까운 평균으로 묶어 Cluster를 나누는 방식
  • k-means 절차
    1. 클러스터의 개수 지정(k)
    2. 그룹의 중심 점(mean)이 무작위로 선택됨
    3. 임의로 선택된 중심 점과 각 점 간의 거리를 계산해서 가장 가까운 중심점의 그룹(군집)으로 선택됨
    4. 선택된 그룹의 점들을 기준으로 중심점을 계산해서 찾고,
    5. 중심점의 변화가 거의 없을 때까지 ⑤ ③~④를 반복
# k means 학습
model = KMeans(n_clusters= 2, n_init = 'auto')
model.fit(x)

# 예측
pred = model.predict(x)
print(pred)

 

적정 K 값 찾기

 

1. Inertia value

  • 군집화가 된 후에, 각 중심점에서 군집의 데이터 간의 거리를 합산한 값
# inertia값 확인
model.inertia_

# k의 갯수에 따라 각 점과의 거리를 계산하여 적정한 k 찾기
kvalues = range(1, 10)
inertias = []

for k in kvalues:
    model = KMeans(n_clusters=k, n_init = 'auto')
    model.fit(x)
    inertias.append(model.inertia_)
# 시각화
plt.figure(figsize = (8, 6))
plt.plot(kvalues, inertias, marker='o')
plt.xlabel('number of clusters, k')
plt.ylabel('inertia')
plt.grid()
plt.show()

 

2. 실루엣 점수 

실루엣 점수 결과 해석
1에 근접 클러스터 간 거리는 멀고, 클러스터 내부의 거리는 가까움(적절)
에 근접 클러스터 간 거리와 클러스터 내부 거리가 비슷(클러스터가 중첩)
-1 에 근접 클러스터링 결과가 부적절

 

from sklearn.metrics import silhouette_score

# 클러스터 개수에 따른 실루엣 점수를 저장할 리스트
kvalues = range(2, 10) # 최소 2개 이상이어야 함.
sil_score = []

for k in kvalues:
    # KMeans 모델 생성
    model = KMeans(n_clusters=k, n_init = 'auto')

    # 모델을 학습하고 예측
    pred = model.fit_predict(x)

    # 실루엣 점수 계산
    sil_score.append(silhouette_score(x, pred))
# 실루엣 점수 시각화
plt.figure(figsize = (8, 6))
plt.plot(kvalues, sil_score, marker='o')
plt.xlabel('n_clusters')
plt.ylabel('Silhouette Score')
plt.grid()
plt.show()

 

 

k 값에 따라 모델을 생성하고 그래프 그리기 함수

def k_means_plot(x, y, k) :
    # 모델 생성
    model = KMeans(n_clusters= k, n_init = 'auto')
    model.fit(x)
    pred = model.predict(x)

    # 군집 결과와 원본 데이터 합치기(concat)
    pred = pd.DataFrame(pred, columns = ['predicted'])
    result = pd.concat([x, pred, y], axis = 1)

    # 중앙(평균) 값 뽑기
    centers = pd.DataFrame(model.cluster_centers_, columns=['x1','x2'])

    # 그래프 그리기
    plt.figure(figsize = (8,6))
    plt.scatter(result['x1'],result['x2'],c=result['predicted'],alpha=0.5)
    plt.scatter(centers['x1'], centers['x2'], s=50,marker='D',c='r')
    plt.grid()
    plt.show()

k_means_plot(x, y, 3) / k_means_plot(x, y, 4)

 

K-Means의 한계

  • 중심점에서의 거리로 군집화
  • 즉, 클러스터가 원형으로 분포되어 있는 경우에는 잘 작동하지만, 아래와 같이 비선형적인 형태의 클러스터를 잘 찾지 못할 수 있음
    • DBSCAN으로 단점 보완이 가능하나 대체적으로 K-Means 사용

각각 k=2, 8

728x90