๋จธ์ ๋ฌ๋์ ๋น์ง๋(unsupervised)ํ์ต
1. ํํ /๋ถํ ๊ธฐ๋ฐ์ ๊ตฐ์ง (Partition-based Clustering)
- ๋น์ทํ ํน์ง์ ๊ฐ๋ ๋ฐ์ดํฐ๋ผ๋ฆฌ ๋ฌถ๋๊ฒ์ด๋ค
- ์ฃผ์ด์ง ๋ฐ์ดํฐ์ ๋ํด ๋ฏธ๋ฆฌ ์ ์๋ ์์ ๊ตฐ์ง์ ํ์ฑํ๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ ํด๋น ๊ตฐ์ง์ ํ ๋นํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค
ex ) K-Means Clustering
2. ๊ณ์ธต์ ๊ตฐ์ง (Hierarchical Clustering)
- ๋ฐ์ดํฐ๋ฅผ ์์ฐจ์ ๋๋ ๊ณ์ธต์ ์ผ๋ก ๊ทธ๋ฃนํํ๋ ์๊ณ ๋ฆฌ์ฆ
- ๋ฐ์ดํฐ ํฌ์ธํธ ๊ฐ์ ๊ฑฐ๋ฆฌ ๋๋ ์ ์ฌ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ฑํ์ฌ ๊ตฐ์ง์ ํ์ฑ
- ๊ณ์ธต์ ์ธ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ด ๊ตฐ์งํ ๊ฒฐ๊ณผ๋ฅผ ๋ค์ํ ์์ค์์ ์ดํด๋ณผ ์ ์์ผ๋ฉฐ, ์๊ฐ์ ์ผ๋ก ํํํ๊ธฐ ์ฝ๋ค
- ์ฌ์ ์ ๊ตฐ์ง์ ๊ฐ์๋ฅผ ์ง์ ํ ํ์๊ฐ ์์ด ํธ๋ฆฌ
- ํฐ ๋ฐ์ดํฐ์ ์ ๋ํด์๋ ๊ณ์ฐ ๋น์ฉ์ด ์ฆ๊ฐํ ์ ์๊ณ , ํน์ ์์ค์์์ ๊ตฐ์งํ ๊ฒฐ๊ณผ๋ฅผ ํด์ํ๋ ๊ฒ์ด ์ด๋ ค์ธ ์ ์๋ค
ex ) ๋ณํฉ ๊ตฐ์งํ (Agglomerative Clustering) , ๋ถํ ๊ตฐ์งํ (Divisive Clustering)
K-Means
- AI(์ธ๊ณต์ง๋ฅ)์ด ์ ๋ ฅ์ธํธ์์ ํจํด๊ณผ ์๊ด๊ด๊ณ๋ฅผ ์ฐพ์๋ด๋ ๋จธ์ ๋ฌ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค.
- ๋น์ง๋ํ์ต ์ค ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๋ฐฉ์์ด๋ค.
- ํ๊ท ์ ์ฐพ์๊ฐ๋ฉฐ y๋ฅผ ์ค์ค๋ก ์ฐพ๋ ๋ฐฉ์์ด๋ค.
- ๊ตฐ์ง์ ์ฌ๋์ด ํ ๋นํด์ผ ํ๋ค.
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# Annual Income (k$) ์ ๋นํด์ Spending Score (1-100) ์ด ๋์ ๊ทธ๋ฃน์ผ๋ก ๋ฌถ๊ธฐ
df
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 |
... | ... | ... | ... | ... | ... |
195 | 196 | Female | 35 | 120 | 79 |
196 | 197 | Female | 45 | 126 | 28 |
197 | 198 | Male | 32 | 126 | 74 |
198 | 199 | Male | 32 | 137 | 18 |
199 | 200 | Male | 30 | 137 | 83 |
nan๊ฐ ์ ๋ฆฌํ๊ธฐ
df.isna().sum()
CustomerID 0
Genre 0
Age 0
Annual Income (k$) 0
Spending Score (1-100) 0
dtype: int64
X๊ฐ ์ ํ๊ธฐ
Genre | Age | Annual Income (k$) | Spending Score (1-100) | |
0 | Male | 19 | 15 | 39 |
1 | Male | 21 | 15 | 81 |
2 | Female | 20 | 16 | 6 |
3 | Female | 23 | 16 | 77 |
4 | Female | 31 | 17 | 40 |
... | ... | ... | ... | ... |
195 | Female | 35 | 120 | 79 |
196 | Female | 45 | 126 | 28 |
197 | Male | 32 | 126 | 74 |
198 | Male | 32 | 137 | 18 |
199 | Male | 30 | 137 | 83 |
๋ฌธ์์ด ์ซ์๋ก ๋ฐ๊พธ๊ธฐ
X['Genre'].unique()
array(['Male', 'Female'], dtype=object)
'Male'๊ณผ 'Female' 2๊ฐ์ด๋ฏ๋ก 0๊ณผ 1๋ก๋ง ๋ฐ๊พธ๋ฉด ๋๊ธฐ๋๋ฌธ์, ์ํซ์ธ์ฝ๋ฉ(3๊ฐ ์ด์)์ด ์๋ ๋ผ๋ฒจ ์ธ์ฝ๋ฉ์ผ๋ก ํ๋ฉด ๋๋ค
from sklearn.preprocessing import LabelEncoder
encoder = LabelEncoder()
X['Genre'] = encoder.fit_transform(X['Genre'])
X
Genre | Age | Annual Income (k$) | Spending Score (1-100) | |
0 | 1 | 19 | 15 | 39 |
1 | 1 | 21 | 15 | 81 |
2 | 0 | 20 | 16 | 6 |
3 | 0 | 23 | 16 | 77 |
4 | 0 | 31 | 17 | 40 |
... | ... | ... | ... | ... |
195 | 0 | 35 | 120 | 79 |
196 | 0 | 45 | 126 | 28 |
197 | 1 | 32 | 126 | 74 |
198 | 1 | 32 | 137 | 18 |
199 | 1 | 30 | 137 | 83 |
sorted(X['Genre'].unique())
['Female', 'Male']
'Female'์ด 0, 'Male'์ด 1์ด๋ผ๋ ๊ฒ์ ์ ์ ์๋ค.
K-means๋ ํผ์ณ์ค์ผ์ผ๋ง ๋จ๊ณ๋ฅผ ๊ฑฐ์น์ง ์๋๋ค
WCSS
from sklearn.cluster import KMeans
KMeans(n_clusters = ???, random_state=10)
n_clusters = ? ๋ช๊ฐ ๊ทธ๋ฃน์ผ๋ก ํ ๊ฑด์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ??? ๋ถ๋ถ์ ์ฐพ์์ผ ํ๋ค ์ด ???๋ฅผ WCSS๋ผ๊ณ ํ๋ค
wcss๋ฅผ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค
wcss = []
for i in range (1, 10+1) :
kmeans = KMeans(n_clusters = i,random_state=10)
kmeans.fit(X)
wcss.append( kmeans.inertia_ )
i๋ฅผ 1๋ถํฐ 10๊น์ง ๋ฐ๋ณตํ์ฌ ๋ฃ์ด๋ณด๋ฉด์, ์ด๋ค ๊ตฐ์ง๊ฐฏ์๊ฐ ์ข์์ง ๊ทธ๋ํ๋ก ๋ณด๋ ค๊ณ ํ๋ค.
random_state๋ random์ seed์ ๊ฐ์ ๊ฐ๋ ์ผ๋ก ๋ณธ์ธ์ด ์ํ๋ ์ซ์ ๋๋ ํ์ฌ์์ ์ ํ ์ซ์๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
(์ด๊ฒ์ด ๋๋ฌ๋๋ฉด ํดํน ๋ณด์์ ์ทจ์ฝํด์ง๋ค)
inertia ?
# ์ฌ๋ฌ ๊ฐ์ ์ํ ๊ฐ๋ฅํ(iterable) ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ๋ฐ๊ณ ๊ฐ ๊ฐ์ฒด๊ฐ ๋ด๊ณ ์๋ ์์๋ฅผ ์ฐจ๋ก๋ก ์ ๊ทผํ ์ ์๋ค
# ๋ง์น ์ท์ ์งํผ๋ฅผ ์ฌ๋ฆฌ๋ ๊ฒ์ฒ๋ผ ์์ธก์ ์๋ ๋ฐ์ดํฐ๋ฅผ ํ๋์ฉ ์ฐจ๋ก๋ก ์ง์ ์ง์ด์ค๋ค
plt.plot(wcss)
plt.show()
# ๋ฐ์ ๊ทธ๋ํ์ฒ๋ผ k๊ฐ์ ๋ํ ๊ด์ฑ์ ์๊ฐํํ ๊ฒ์ elbow method(ํ๊ฟ์น) ๋ฐฉ์์ด๋ผ๊ณ ํ๋ค.
์ฌ๊ธฐ์ ๊ตฐ์ง์ด ์ ๊ฒ ์์์๋ก ์ค์ฐจ๊ฐ ํฌ๊ณ , ๊ตฐ์ง์ด ์ฌ๋ฌ๊ฐ ์์์๋ก ์ค์ฐจ๊ฐ ์ ๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
๊ทธ๋ฌ๋ฏ๋ก ์ฌ๋์ด ๋ณด๊ธฐ์ ์ค์ฐจ๊ฐ ์ ์ผ๋ฉด์, ๊ตฐ์ง์ด ๋๋ฌด ํฌ์ง ์์ ํจ์จ์ ์ธ ๊ตฐ์ง ๊ฐฏ์๋ฅผ ์ ํด์ผ ํ๋ค
๊ทธ๋ํ๋ก ๋ณด์์ ๋, 5๊ฐ์ ๊ตฐ์ง์ด ์ ๋นํ ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํ์๋ค.
์์ธกํ๊ธฐ
KMeans(n_clusters = 5, random_state=10)
y_pred = kmeans.fit_predict(X)
y_pred
df['Group'] = y_pred
df
CustomerID | Genre | Age | Annual Income (k$) | Spending Score (1-100) | Group | |
0 | 1 | Male | 19 | 15 | 39 | 3 |
1 | 2 | Male | 21 | 15 | 81 | 1 |
2 | 3 | Female | 20 | 16 | 6 | 3 |
3 | 4 | Female | 23 | 16 | 77 | 1 |
4 | 5 | Female | 31 | 17 | 40 | 3 |
... | ... | ... | ... | ... | ... | |
195 | 196 | Female | 35 | 120 | 79 | 2 |
196 | 197 | Female | 45 | 126 | 28 | 0 |
197 | 198 | Male | 32 | 126 | 74 | 2 |
198 | 199 | Male | 32 | 137 | 18 | 0 |
199 | 200 | Male | 30 | 137 | 83 | 2 |
# ์ฐ๊ฐ income(์์ )์ ๋นํด ์๋น ์ ์๊ฐ ๋์ ๊ทธ๋ฃน 4๋ฅผ ๊ฐ์ ธ์๋ดค๋ค
CustomerID | Genre | Age | Annual Income (k$) | Spending Score (1-100) | Group | |
46 | 47 | Female | 50 | 40 | 55 | 4 |
47 | 48 | Female | 27 | 40 | 47 | 4 |
48 | 49 | Female | 29 | 40 | 42 | 4 |
49 | 50 | Female | 31 | 40 | 42 | 4 |
50 | 51 | Female | 49 | 42 | 52 | 4 |
... | ... | ... | ... | ... | ... | ... |
120 | 121 | Male | 27 | 67 | 56 | 4 |
121 | 122 | Female | 38 | 67 | 40 | 4 |
122 | 123 | Female | 40 | 69 | 58 | 4 |
126 | 127 | Male | 43 | 71 | 35 | 4 |
142 | 143 | Female | 28 | 76 | 40 | 4 |