머신러닝(파이썬) - K-Means, Hierarchical Clustering

LSH·2023년 7월 25일
0

교육 정보

  • 교육 명: 경기미래기술학교 AI 교육
  • 교육 기간: 2023.05.08 ~ 2023.10.31
  • 오늘의 커리큘럼:
    머신러닝
    (7/17 ~ 7/28)
  • 강사: 이현주, 이애리 강사님
  • 강의 계획:
    1. 머신러닝

K-Means, Hierarchical Clustering

1

# warning메시지 무시
import warnings
warnings.filterwarnings('ignore')

# 한글, 마이너스 부호가 잘 보이는지 확인하기
import matplotlib.pyplot as plt

plt.rc('font', family='Malgun Gothic')

# 마이너스(음수)부호 설정
plt.rc("axes", unicode_minus=False)

plt.figure(figsize=(5,2))

# plt.title('한글, 마이너스 부호 확인하기', fontsize=20)
# plt.plot([-10, 0, 10], [-1, 0, 1])
# plt.show()

# 필요한 라이브러리 import
#numpy, pandas, matplotlib,pyplot, seaborn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

file_path = 'game_usage.csv'
df_ori = pd.read_csv(file_path)

df = df_ori[:]
print(id(df), id(df_ori))

# 게임유저를 게임시간과 레벨을 이용하여 산점도 시각화
# X에는 게임시간, y에는 게임레벨
x = df['time spent']
y = df['game level']

# 게임 이용자 분석: 산점도 그래프
plt.figure(figsize=(5,5))
plt.scatter(x, y)

# 게임하는 고객을 k-means를 이용해 군집화
import random
from sklearn.cluster import KMeans


def rand_color(num=1):
  col = list()
  for _ in range(num):
    col.append("#" + "".join([random.choice('0123456789ABCDEF') for _ in range(6)]))
  return col


def kmeans_predict_plot(data, k):
    # k-means 분류기 만들고 data 분류하기
    model = KMeans(n_clusters = k) # 모델 생성, 초기화
    model.fit(data) # 학습
    labels = model.predict(data) # 예측 - 클러스터 결정
    # print(data)
    # print(labels)


    # 결과를 산점도로 시각화하기
    colors = np.array(rand_color(k))
    print(colors)
    plt.figure(figsize=(5,5))
    plt.title(f'KMC, k = {k}')
    print(labels)
    plt.scatter(data[:, 0], data[:, 1], color=colors[labels])


game_data = np.column_stack(x, y)
kmeans_predict_plot(game_data, k=2)
kmeans_predict_plot(game_data, k=3)
kmeans_predict_plot(game_data, k=4)


# 거리를 기반으로 하는 데이터에서 x축의 표시범위와 y축의 표시범위를 보정해보면
# 아래의 그래프의 군집화는 게임의 레벨에서만 분류가 일어났음을 알 수 있다.

# 레벨 값이 절대값이 커서 그런듯 -> 스케일링 필요

kmeans_predict_plot(game_data, k=4)
plt.xlim(0, 1000)
plt.ylim(0, 1000)

# 각각의 특징들의 값을 모두 0~1 사이의 범위가 되도록 동일한 규모로 변경하는 작업 : 정규화 (normalizarion)

# 정규화
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
n_data = scaler.fit_transform(game_data)
print(n_data[:, 0].min(), n_data[:, 0].max())
print(n_data[:, 1].min(), n_data[:, 1].max())

# 표준화
from sklearn.preprocessing import StandardScaler

std_scaler = StandardScaler()
n_data_std_scaled = std_scaler.fit_transform(game_data)

print(n_data_std_scaled[:, 0].std(), n_data_std_scaled[:, 1].std())
print(n_data_std_scaled[:, 0].mean().round(2), n_data_std_scaled[:, 1].mean().round(2)) #평균이 거의 0

# n_data 4개의 군집 생성
# X와 Y의 모든 값이 반영된 군집 데이터를 얻을 수 있다.
kmeans_predict_plot(n_data, k=4)

#gamer_data 4개의 군집 생성
kmeans_predict_plot(n_data_std_scaled, k=5)

# 덴드로그램에서 어디를 자르냐에 따라서 몇개의 군집으로 나누어질지가 결정됨

# Hierarchical Clustering
import scipy.cluster.hierarchy as sch

fig = plt.figure(figsize=(16,10))
sch.dendrogram(sch.linkage(n_data, method='ward'))
plt.title('Dendrogram')
plt.xlabel('game usage time')
plt.ylabel('distance')
plt.axhline(2, c='k', lw=0.5, ls='--')
plt.show()
# 거리 계산 방법으로 요즘 가장 많이 사용되는 Ward linkage 사용
# (클러스터 내의 분산을 최소화하는 방식으로 클러스터를 합치는 방법)

# import
from sklearn.cluster import AgglomerativeClustering

hc = AgglomerativeClustering(n_clusters=4, affinity='euclidean', linkage='ward')
y_hc = hc.fit_predict(n_data)
#n_cluster : 위에 Dendrogram 보고 정한 갯수 (거리 2.0에서의 그룹 갯수)

plt.figure(figsize=(5,5))
plt.title('Agglomerative')
plt.scatter(n_data[:, 0], n_data[:, 1], c=y_hc, cmap='coolwarm')

plt.show()
profile
:D

1개의 댓글

comment-user-thumbnail
2023년 7월 25일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기