인공지능/공부

고급 인공지능 활용 과제 5 - 분류하기, 클러스터링

이게될까 2024. 4. 13. 22:22
728x90
728x90
from google.colab import drive
drive.mount('/content/drive')

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/titanic.csv')
data = data.drop(['Name','Ticket'],axis=1) # 이름과 티켓 값은 생존과 관련 없기 때문이다.
data = pd.get_dummies(data,columns=['Sex','Embarked'],drop_first = True)# 데이터 세분화 하면서 데이터 갯수 줄이기 (남자 여자에서 하나 지우고, 3개중에 하나 지우기)
data['family'] = data['SibSp'] + data['Parch'] # 가족을 한곳에 모으기
data.drop(['SibSp','Parch'],axis = 1, inplace = True)
data.head()
from sklearn.preprocessing import MinMaxScaler # 이전 knn에서 제일 좋은 값이 나왔던 최대 최소 스케일링을 사용해봤다.
mm_scaler = MinMaxScaler()
mm_scaled = mm_scaler.fit_transform(data)
mm_scaled = pd.DataFrame(mm_scaled, columns = data.columns)
round(mm_scaled.describe(),2)
from sklearn.cluster import KMeans

distance = [] # 이너셔 확인 단계
for k in range(2, 10):
  k_model = KMeans(n_clusters=k)
  k_model.fit(mm_scaled)
  labels = k_model.predict(mm_scaled)
  distance.append(k_model.inertia_)

sns.lineplot(x=range(2, 10), y=distance)

 

from sklearn.metrics import silhouette_score # 시루엣 스코어 계산
silhouette = []
for k in range(2, 10):
  k_model = KMeans(n_clusters=k)
  k_model.fit(mm_scaled)
  labels = k_model.predict(mm_scaled) # 군집 안거리,밖의 거리도 계산하기 때문에 오래걸린다.
  silhouette.append(silhouette_score(mm_scaled, labels))# 데이터와 라벨 둘다가 필요하다.

sns.lineplot(x=range(2, 10), y=silhouette) # 높을수록 좋은 군집 분류이다. # 9에서 이너셔도 낮고 실루엣 스코어도 높으므로 제일 좋다고 볼 수 있다.

k_model = KMeans(n_clusters=9)# 9일때가 가장 좋으므루
k_model.fit(mm_scaled)
labels = k_model.predict(mm_scaled)
mm_scaled['label'] = labels# 추가해서 저장해놓기
mm_scaled.head()
scaled_df_mean = mm_scaled.groupby('label').mean()
scaled_df_count = mm_scaled.groupby('label').count()['Survived']
scaled_df_count = scaled_df_count.rename('count')
scaled_df_all = scaled_df_mean.join(scaled_df_count)#데이터 합치기
scaled_df_all
round(mm_scaled.describe(),2)
round(data.describe(),2)

마지막 3개의 표를 비교해서 9개를 어떻게 나누었는지 볼 수 있다.
0, 3,7,8 그룹들을 대부분 살았고, 출항지를 기준으로 많이 나누어져 있는 것을 볼 수 있다.

    • 0그룹 - P클레스는 1이고, 살았고, 여자가 대부분이며 출항지가 c이다.
    • 1그룹 - 피클레스는 1과 2가 섞여있으며 남자고 다죽었다. 출항지가 s이다.
    • 2그룹 - 피클레스는 3이며 다 죽었꼬, 남자이다. 출항지가 S이다. 1그룹에 비해선 가족이 많고 어리다. 제일 많은 사람이 포함되어 있다.
    • 3그룹 - 피클레스는 대부분이 2 이며 다 살았고, 다 여자이며, 출항지가 s이다.
    • 4그룹 - 피클레스는 대부분이 2이며, 다 죽었꼬, 전부 남자이며, c항에서 출항했다.
    • 5그룹 - 피클레스가 대부분 3이며 다 죽었꼬, 여자이며 출항지가 대부분 s이다. 가족도 제일 많았다.
    • 6그룹 - 피클레스 대부분이 3이며, 대부분이 죽었고 대부분이 남자이다. 출항지가 q인 사람들이다.
    • 7그룹 - 대부분이 피클레스가 3이며, 다 살았고, 여자이며 대부분이 출항지가 q와 c이다.
    • 8그룹 - 대부분 피클레스가 2이며 다 살았고, 남자이다. s에서 대부분 출항했다.

이렇게 겹치는 부분 없이 나뉘게 된다.

  •  

혹시 몰라서 10이상도 해봤다.

data = pd.read_csv('/content/drive/MyDrive/Colab Notebooks/titanic.csv')
data = data.drop(['Name','Ticket'],axis=1) # 이름과 티켓 값은 생존과 관련 없기 때문이다.
data = pd.get_dummies(data,columns=['Sex','Embarked'],drop_first = True)# 데이터 세분화 하면서 데이터 갯수 줄이기 (남자 여자에서 하나 지우고, 3개중에 하나 지우기)
data['family'] = data['SibSp'] + data['Parch'] # 가족을 한곳에 모으기
data.drop(['SibSp','Parch'],axis = 1, inplace = True)
data.head()
from sklearn.cluster import KMeans
from sklearn.preprocessing import MinMaxScaler # 이전 knn에서 제일 좋은 값이 나왔던 최대 최소 스케일링을 사용해봤다.
mm_scaler = MinMaxScaler()
mm_scaled = mm_scaler.fit_transform(data)
mm_scaled = pd.DataFrame(mm_scaled, columns = data.columns)
round(mm_scaled.describe(),2)
distance = [] # 이너셔 확인 단계
for k in range(2, 15):
  k_model = KMeans(n_clusters=k)
  k_model.fit(mm_scaled)
  labels = k_model.predict(mm_scaled)
  distance.append(k_model.inertia_)

sns.lineplot(x=range(2, 15), y=distance)

from sklearn.metrics import silhouette_score # 시루엣 스코어 계산
silhouette = []
for k in range(2, 15):
  k_model = KMeans(n_clusters=k)
  k_model.fit(mm_scaled)
  labels = k_model.predict(mm_scaled) # 군집 안거리,밖의 거리도 계산하기 때문에 오래걸린다.
  silhouette.append(silhouette_score(mm_scaled, labels))# 데이터와 라벨 둘다가 필요하다.

sns.lineplot(x=range(2, 15), y=silhouette) # 높을수록 좋은 군집 분류이다. # 13에서 제일 좋다고 볼 수 있따.

위에서 한번 분류했으므로 간단하게 한번만 쭉 본다는 느낌으로 해봤다.

k_model = KMeans(n_clusters=13)# 13일때가 가장 좋으므루
k_model.fit(mm_scaled)
labels = k_model.predict(mm_scaled)
mm_scaled['label'] = labels# 추가해서 저장해놓기
scaled_df_mean = mm_scaled.groupby('label').mean()
scaled_df_count = mm_scaled.groupby('label').count()['Survived']
scaled_df_count = scaled_df_count.rename('count')
scaled_df_all = scaled_df_mean.join(scaled_df_count)#데이터 합치기
scaled_df_all

피클레스와 성별, 출항지가 좀더 깔끔하게 나뉘었지만 데이터가 점점 더 많아지면서 가시성이 낮아졌다. 아까이 9개가 훨씬 가시성이 좋은 느낌이다. 그래도 생존에 대해 좀더 확실하게 나누어 진 13일 때의 결과이다

728x90