도찐개찐

[머신러닝-비지도] 01. 군집분석 본문

PYTHON/데이터분석

[머신러닝-비지도] 01. 군집분석

도개진 2023. 1. 4. 10:01

■ 데이터를 보다 잘 이해하기 위해 하는 클러스터링(Clustering)

클러스터링은 어떤 데이터가 주어졌을 때

1) 하나의 군집에 있는 각 데이터 포인트가 서로 비슷하고
2) 다른 군집에 있는 데이터와는 다르게

데이터를 분류해주는 작업이다. 이미 주어져 있는 데이터를 가지고 군집을 만들기 때문에 기술(descriptive)적인 분석을 가능하게 해준다. 아래 그림에서 오른쪽은 색깔로 레이블이 표시된 실제 데이터이다. 그렇지만 만약 각 데이터의 정체를 모른다면?

 

그림의 왼쪽과 같이 가까운 데이터끼리 묶는 작업이 필요하다. 물론 현실에서 데이터가 저렇게 예쁘게 거리를 두고 있기 만무하지만, 하나의 군집 내 데이터끼리의 거리를 최소화(빨간 화살표의 길이)하고, 각 군집끼리의 거리(파란 화살표의 길이) 를 최대화하여 군집을 만들어내는 것이 클러스터링의 목적이다. 왜냐고? 데이터의 구조를 제대로, 잘 이해하기 위해서!

클러스터링은 대표적인 비지도 학습(Unsupervised learning) 방식이다. 레이블(즉, 위 그림에서 ‘빨간색’, ‘파란색’, ‘초록색’ 이라는 이름이 붙어져 있지 않은 상태)이 없는 데이터를 가지고, 그 본질적인 구조를 탐색하기 위한 작업이기 때문이다.

■ 클러스터링 활용 분야

클러스터링은 시장의 세그멘테이션을 할 때 유용한데, 하나의 시장을 여러 고객의 하위군집으로 구분하는 것을 말한다. 클러스터링의 평가는 하나의 클러스터 내의 고객들의 구매 패턴이 비슷하고, 그들의 구매 패턴이 다른 군집의 고객들과는 구분되는지 확인하여 파악할 수 있다.

또 다른 예시로는 문서 데이터의 클러스터링이 있겠다. 이 때 목적은 각 문서에서 나타나는 키워드를 중심으로 각 문서끼리 얼마나 비슷한지, 다른지를 분석하는 것이다. 이를 위해서는 먼저 각 문서에 나타나는 어떤 용어들이 자주 나타나는지를 확인하고, 빈도수에 따라 유사성(similarity)를 구분한다. 검색엔진은 이를 바탕으로 우리가 어떤 키워드를 검색했을 때 그 키워드 관련 문서들을 보여준다.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from yellowbrick.cluster import SilhouetteVisualizer
from yellowbrick.cluster import KElbowVisualizer
from sklearn.cluster import KMeans

과일, 채소 군집분석

fresh = pd.read_csv('../data/fresh.csv', encoding='euc-kr')
fresh.columns = ['name', 'sweet', 'crunchy', 'class']
fresh.head()
  name sweet crunchy class
0 포도 8 5 과일
1 생선 2 2 단백질
2 당근 6 10 채소
3 오렌지 7 3 과일
4 샐러리 3 8 채소
data = fresh.iloc[:, 1:3]
target = fresh.iloc[:, 3]
fig, ax = plt.subplots(2, 3, figsize=(15,8))
for i in [2, 3, 4, 5, 6, 7]:
    km = KMeans(n_clusters=i, random_state=2211230945)
    q, mod = divmod(i+1, 3)
    visualizer = SilhouetteVisualizer(km, ax=ax[q-1][mod])
    visualizer.fit(data) 
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
findfont: Generic family 'sans-serif' not found because none of the following families were found: Arial, Liberation Sans, Bitstream Vera Sans, sans-serif

km = KMeans()
# viszr = KElbowVisualizer(km, k=(2,7))
# viszr = KElbowVisualizer(km, k=(2,7), timings=False)
viszr = KElbowVisualizer(km, k=(2,7), metric='calinski_harabasz', timings=False)
viszr.fit(data)
viszr.show()
/opt/miniconda3/lib/python3.9/site-packages/yellowbrick/utils/kneed.py:156: YellowbrickWarning: No 'knee' or 'elbow point' detected This could be due to bad clustering, no actual clusters being formed etc.
  warnings.warn(warning_message, YellowbrickWarning)
/opt/miniconda3/lib/python3.9/site-packages/yellowbrick/cluster/elbow.py:374: YellowbrickWarning: No 'knee' or 'elbow' point detected, pass `locate_elbow=False` to remove the warning
  warnings.warn(warning_message, YellowbrickWarning)
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
findfont: Generic family 'sans-serif' not found because none of the following families were found: Arial, Liberation Sans, Bitstream Vera Sans, sans-serif
findfont: Font family ['sans-serif'] not found. Falling back to DejaVu Sans.
findfont: Generic family 'sans-serif' not found because none of the following families were found: Arial, Liberation Sans, Bitstream Vera Sans, sans-serif

<AxesSubplot:title={'center':'Calinski Harabasz Score Elbow for KMeans Clustering'}, xlabel='k', ylabel='calinski harabasz score'>
km = KMeans(n_clusters=4, random_state=2211230945)
km.fit(data)
KMeans(n_clusters=4, random_state=2211230945)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
plt.scatter(data.iloc[:, 0], data.iloc[:, 1], c=km.labels_, cmap='Paired')
plt.show()

농구선수 게임데이터를 이용해서 포지션 군집 분석

bbp = pd.read_csv('../data/bbplayer.csv')
data = bbp.iloc[:, 2:8]
bbp.head()
  Player Pos 3P 2P TRB AST STL BLK
0 Alex Abrines SG 1.4 0.6 1.3 0.6 0.5 0.1
1 Steven Adams C 0.0 4.7 7.7 1.1 1.1 1.0
2 Alexis Ajinca C 0.0 2.3 4.5 0.3 0.5 0.6
3 Chris Andersen C 0.0 0.8 2.6 0.4 0.4 0.6
4 Will Barton SG 1.5 3.5 4.3 3.4 0.8 0.5
fig, ax = plt.subplots(2, 3, figsize=(15,8))
for i in [2, 3, 4, 5, 6, 7]:
    km = KMeans(n_clusters=i, random_state=2211230945)
    q, mod = divmod(i+1, 3)
    visualizer = SilhouetteVisualizer(km, ax=ax[q-1][mod])
    visualizer.fit(data) 

km = KMeans(random_state=2211230945)

# viszr = KElbowVisualizer(km, k=(2,7), locate_elbow=False)
viszr = KElbowVisualizer(km, k=(2,7), metric='calinski_harabasz', timings=False)
viszr.fit(data)
viszr.show()

<AxesSubplot:title={'center':'Calinski Harabasz Score Elbow for KMeans Clustering'}, xlabel='k', ylabel='calinski harabasz score'>
km = KMeans(n_clusters=2, random_state=2211230945)
km.fit(data)
KMeans(n_clusters=2, random_state=2211230945)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
plt.scatter(data.iloc[:, 0], data.iloc[:, 1], c=km.labels_, cmap='Paired')
plt.show()

참고 URL : https://lucy-the-marketer.kr/ko/growth/clustering/

728x90
Comments