본문 바로가기
머신러닝 & 딥러닝

12. KMeans

by 곽정우 2024. 6. 13.

1. Clusters(클러스터)

  • 유사한 특성을 가진 개체들의 집합
  • 고객 분류, 유전자 분석, 이미지 분할
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=100, centers=3, random_state=2023)
X=pd.DataFrame(X)
X

y

sns.scatterplot(x=X[0], y=X[1], hue=y)

from sklearn.cluster import KMeans
km = KMeans(n_clusters=3)
km.fit(X)
pred = km.predict(X)

sns.scatterplot(x=X[0], y=X[1], hue=pred)

km = KMeans(n_clusters=5)
km.fit(X)
pred = km.predict(X)

sns.scatterplot(x=X[0], y=X[1], hue=pred)

# 평가값: 하나의 클러스터안에 중심점으로부터 각각의 데이터 거리를 합한 값의 평균
km.inertia_

inertia_list = []

for i in range(2, 11):
    km = KMeans(n_clusters=i)
    km.fit(X)
    inertia_list.append(km.inertia_)

inertia_list

# 퍼짐 정도를 다합친값이 크면 너무 멀리 퍼졌다는 것이며 점점 너무 작아지면 
# 가까운 것끼리 분류는 한것이므로 꺽이는 부분이 적절하다 판단 할 수 있다.
# 엘보우 메서드

sns.lineplot(x=range(2, 11), y=inertia_list)


2. marketing 데이터셋

marketing.csv
0.17MB

mkt_df = pd.read_csv('/content/drive/MyDrive/KDT/6.머신러닝과 딥러닝/Data/marketing.csv')
mkt_df

mkt_df.info()

영어                 한글                     
---------------------- --------------------------
ID                   고객 아이디              
Year_Birth           출생 연도                
Education            학력                     
Marital_Status       결혼 여부                
Income               소득                     
Kidhome              어린이 수                
Teenhome             청소년 수                
Dt_Customer          고객 등록일              
Recency              마지막 구매일로부터 경과일 
MntWines             와인 구매액              
MntFruits            과일 구매액              
MntMeatProducts      육류 제품 구매액         
MntFishProducts      어류 제품 구매액         
MntSweetProducts     단맛 제품 구매액         
MntGoldProds         골드 제품 구매액         
NumDealsPurchases    할인 행사 구매 수        
NumWebPurchases      웹에서의 구매 수         
NumCatalogPurchases  카탈로그에서의 구매 수   
NumStorePurchases    매장에서의 구매 수       
NumWebVisitsMonth    월별 웹 방문 수          
Complain             불만 여부
mkt_df.drop('ID', axis=1, inplace=True)
mkt_df.describe()

mkt_df.sort_values('Year_Birth')

mkt_df.sort_values('Income', ascending=False)

# mkt_df = mkt_df[mkt_df['Income' < 20000]] # NaN이 저장되지 않음
mkt_df = mkt_df[mkt_df['Income'] != 666666]
mkt_df.sort_values('Income', ascending=False)

mkt_df = mkt_df.dropna()
mkt_df.isna().mean()

mkt_df['Dt_Customer'] = pd.to_datetime(mkt_df['Dt_Customer'], format='%d-%m-%Y')
mkt_df.info()

# 마지막으로 가입된 사람을 기준으로 가입 날짜(달) 구하기
# pass month

mkt_df['pass_month'] = (
    (mkt_df['Dt_Customer'].max().year * 12 + mkt_df['Dt_Customer'].max().month) - 
    (mkt_df['Dt_Customer'].dt.year * 12 + mkt_df['Dt_Customer'].dt.month)
)
mkt_df.head()

mkt_df.drop('Dt_Customer',axis=1, inplace=True)
mkt_df.head()

# mkt_df['Total_mnt'] = 와인 + 과일 + 육류 + 어류 + 단맛 + 골드

mkt_df['Total_mnt'] = mkt_df[[
    'MntWines', 
    'MntFruits', 
    'MntMeatProducts', 
    'MntFishProducts', 
    'MntSweetProducts', 
    'MntGoldProds'
]].sum(axis=1)
mkt_df.head()

# mkt_df['Children'] = 아이, 십대

mkt_df['Children'] = mkt_df[['Kidhome', 'Teenhome']].sum(axis=1)
mkt_df.head()

mkt_df.drop(['Kidhome', 'Teenhome'], axis=1, inplace=True)
mkt_df.info()

mkt_df['Education'].value_counts()

mkt_df['Marital_Status'].value_counts()

# # Marital_Status에서 파트너(Partner)와 싱글(Single)로 묶어줄 내용을 합치기

mkt_df['Marital_Status'] = mkt_df['Marital_Status'].replace({
    'Married': 'Partner', 
    'Together': 'Partner', 
    'Single': 'Single', 
    'Divorced': 'Single', 
    'Widow': 'Single', 
    'Alone': 'Single', 
    'Absurd': 'Single', 
    'YOLO': 'Single'
})
mkt_df['Marital_Status'].value_counts()

# 원 핫 인코딩 하기

mkt_df = pd.get_dummies(mkt_df, columns=['Education', 'Marital_Status'])
mkt_df.head()

from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit_transform(mkt_df)

pd.DataFrame(ss.fit_transform(mkt_df))

ss_df = pd.DataFrame(ss.fit_transform(mkt_df))
ss_df

ss_df = pd.DataFrame(ss.fit_transform(mkt_df), columns=mkt_df.columns)
ss_df


3. KMeans

  • k개의 중심점을 찍은 후에 이 중심점에서 각 점간의 거리의 합이 가장 최소화가 되는 중심점 k의 위치를 찾고, 이 중심점에서 가까운 점들을 중심점을 기준으로 묶는 알고리즘
  • k개의 클러스터의 수는 정해줘야 함
inertia_list = []

for i in range(2, 11):
    km = KMeans(n_clusters=i, random_state=2024)
    km.fit(ss_df)
    inertia_list.append(km.inertia_)

sns.lineplot(x=range(2, 11), y=inertia_list)


4. 실루엣 스코어

  • 군집화의 품질을 평가하는 지표로, 각 데이터 포인트가 자신이 속한 군집과 얼마나 잘 맞는지, 그리고 다른 군집과 얼마나 잘 구분되는지를 측정
  • -1에서 1사이의 값을 가지며, 값이 클수록 군집화의 품질이 높음을 나타냄
from sklearn.metrics import silhouette_score
score = []

for i in range(2, 11):  # 최소 2개의 그룹으론 나눠지기 때문에 2부터 시작
  km = KMeans(n_clusters=i, random_state=2024)
  km.fit(ss_df)
  pred = km.predict(ss_df)
  score.append(silhouette_score(ss_df, pred))
# 스코어 수가 가장 큰 x값이 cluster의 k값으로 설정하는 것이 가장 깔끔함

sns.lineplot(x=range(2, 11), y=score)

km = KMeans(n_clusters=4, random_state=2024)

# 학습
km.fit(ss_df)

# 예측

pred = km.predict(ss_df)
pred

# 해당 데이터에 파생변수로 군집 번호를 생성하기

mkt_df['label'] = pred
mkt_df

# 군집된 종류 개수 알아보기

mkt_df['label'].value_counts()

'머신러닝 & 딥러닝' 카테고리의 다른 글

14. 파이토치로 구현한 선형회귀  (0) 2024.06.13
13. 파이토치(Pytorch)  (0) 2024.06.13
11. 다양한 모델 적용  (0) 2024.06.13
10. lightGBM  (0) 2024.06.13
9. 랜덤 포레스트  (0) 2024.06.12