3 분 소요

K-Means Clustering

Unsupervised Learning 이다.

k 개의 그룹을 만든다. 즉, 비슷한 특징을 갖는 것들끼리 묶는것

다음을 두개, 세개, 네개 그룹 등등 원하는 그룹으로 만들 수 있다.

12

알고리즘

12

12

12 12

12

12

12

12

또다시 중심에 직교하는 선을 긋고, 자신의 영역안에 있는 것들을 자신의 색으로 바꾼다.

12

12

12

12

12

중심을 이동해서, 영역을 나눴는데, 나눈 영역안에 다른 카테고리가 더이상 나타나지 않으면, 끝낸다.

12

Random Initialization Trap

다음과 같은 데이터 분포가 있다고 치자.

12

우리가 원하는 클러스터링 그룹화는, 아래와 같은 것이다.

12

12

12 12

12

12 원치 않는 그룹화가 되어버렸다.

12

위와 같은 문제는 해결한것이, K-Means++ 알고리즘이다.

12

Choosing the right number of clusters

몇개로 분류할지는 어떻게 결정하는가? K의 갯수를 정하는 방법

within-cluster sums of squares

12

센터가 원소들과의 거리가 멀수록 값이 커진다. 따라서 최소값에 가까워지는 갯수를 뽑되, 갯수가 너무 많아지면 차별성이 없어진다.

12

12

K-Means 모델링

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
df = pd.read_csv('Mall_Customers.csv')
df.head()
CustomerID Genre Age Annual Income (k$) Spending Score (1-100)
0 1 Male 19 15 39
1 2 Male 21 15 81
2 3 Female 20 16 6
3 4 Female 23 16 77
4 5 Female 31 17 40
# Nan 있는지 확인
df.isna().sum()
CustomerID                0
Genre                     0
Age                       0
Annual Income (k$)        0
Spending Score (1-100)    0
dtype: int64

1. 데이터 가공

# Unsupervised learnig 이므로 , y값은 존재하지 않는다.
# X 값 셋팅
X = df.iloc[:,3:]

2. 모델링

from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3, random_state=42)
y_pred = kmeans.fit_predict(X)
df['group'] = y_pred
# y_pred 의 값은, 각 행(사람)의 그룹 정보를 가지고 있다.
# 따라서 이 그룹정보는 원래의 데이터 프레임에 추가를 해줘야 이용할 수 있다.
df
CustomerID Genre Age Annual Income (k$) Spending Score (1-100) group
0 1 Male 19 15 39 0
1 2 Male 21 15 81 0
2 3 Female 20 16 6 0
3 4 Female 23 16 77 0
4 5 Female 31 17 40 0
... ... ... ... ... ... ...
195 196 Female 35 120 79 2
196 197 Female 45 126 28 1
197 198 Male 32 126 74 2
198 199 Male 32 137 18 1
199 200 Male 30 137 83 2

200 rows × 6 columns

# 적절한 k 값을 찾기위해서는, WCSS 값을 확인해야 한다.
# 따라서 K를 1부터 10까지 다 수행해서, WCSS값은 리스트에 저장한다.
wcss = []
for k in range(1,11):
    kmeans = KMeans(n_clusters =k, random_state=42)
    # Wcss 값만 확인 할거니까, fit 함수만 이용하면 된다.
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)
C:\Users\5-15\Anaconda3\lib\site-packages\sklearn\cluster\_kmeans.py:881: UserWarning: KMeans is known to have a memory leak on Windows with MKL, when there are less chunks than available threads. You can avoid it by setting the environment variable OMP_NUM_THREADS=1.
  warnings.warn(
# 엘보우 메소드를 이용하기 위해서, 차트로 표시한다.
plt.plot(range(1,11),wcss)
plt.title('The elbow method')
plt.xlabel('Number of Clusters')
plt.ylabel('WCSS')
plt.show()

12

kmeans = KMeans(n_clusters=5, random_state=42)
y_pred = kmeans.fit_predict(X)
df['Group'] = y_pred
df
CustomerID Genre Age Annual Income (k$) Spending Score (1-100) group Group
0 1 Male 19 15 39 0 2
1 2 Male 21 15 81 0 3
2 3 Female 20 16 6 0 2
3 4 Female 23 16 77 0 3
4 5 Female 31 17 40 0 2
... ... ... ... ... ... ... ...
195 196 Female 35 120 79 2 4
196 197 Female 45 126 28 1 1
197 198 Male 32 126 74 2 4
198 199 Male 32 137 18 1 1
199 200 Male 30 137 83 2 4

200 rows × 7 columns

3. 데이터 시각화 및 실습

sb.scatterplot(data= df,x='Annual Income (k$)',y='Spending Score (1-100)')
plt.show()

12

plt.figure(figsize=[12,8])
plt.scatter(X.values[y_pred == 0, 0], X.values[y_pred == 0, 1], s = 100, c = 'red', label = 'Cluster 1')
plt.scatter(X.values[y_pred == 1, 0], X.values[y_pred == 1, 1], s = 100, c = 'blue', label = 'Cluster 2')
plt.scatter(X.values[y_pred == 2, 0], X.values[y_pred == 2, 1], s = 100, c = 'green', label = 'Cluster 3')
plt.scatter(X.values[y_pred == 3, 0], X.values[y_pred == 3, 1], s = 100, c = 'cyan', label = 'Cluster 4')
plt.scatter(X.values[y_pred == 4, 0], X.values[y_pred == 4, 1], s = 100, c = 'magenta', label = 'Cluster 5')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s = 300, c = 'yellow', label = 'Centroids')
plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()

12

# 1. 그룹이 3인 사람들의 데이터를 가져오세요
df_3 = df[df['Group'] == 3]
# 2. 그룹이 3인 사람들의 수입 평균은 얼마입니까?
df_3['Annual Income (k$)'].mean()
25.727272727272727
# 3. 그룹별 소비지표를 나타내되, 평균값과 최대값 두개를 보여주세요.
pd.pivot_table(df,index=['Group'],aggfunc=[np.mean,np.max],values='Spending Score (1-100)')
mean amax
Spending Score (1-100) Spending Score (1-100)
Group
0 49.518519 61
1 17.114286 39
2 20.913043 40
3 79.363636 99
4 82.128205 97
# 4. 각 그룹별 수입과 소비지표의 평균을 구하세요
pd.pivot_table(df,index=['Group'],aggfunc=[np.mean],values=['Annual Income (k$)','Spending Score (1-100)'])
mean
Annual Income (k$) Spending Score (1-100)
Group
0 55.296296 49.518519
1 88.200000 17.114286
2 26.304348 20.913043
3 25.727273 79.363636
4 86.538462 82.128205

댓글남기기