목차
clustering 군집화
군집화는 비지도 unsupervised 알고리즘이다. cluster이란 비슷한 데이터들끼리 묶여있는 집단을 말한다.
어떤 데이터셋은 label이 정해져있지 않다. 이런 경우에는 cluster을 여러 개 만들어서 비슷한 성질을 가진 데이터들을 묶고, 그 데이터 묶음에 cluster을 부여한다.
clustering applications
- 고객 구매 패턴
- 새로운 고객에게 신간 책과 영화 추천
- 신용카드 부정 사용 파악
- 고객 분류
- 고객 신용 위험 진단
- 고객 추천 기사
- 환자 행동 분석
clustering 쓰는 이유
데이터 탐색에 좋다.
대략적으로 데이터를 일반화하거나, 사이즈를 줄일 수 있다.
이상치를 발견한다.
중복을 찾는다.
다양한 clustering algorithms
1) partioned-based
반원형태의 집단으로 묶인다.
중간, 대용량 데이터셋이 쓰며, 상대적으로 효율적이다
K-means
2)Hierarchical Clustering
트리형식으로 상하 관계가 있다. 직관적으며 작은 데이터셋에 쓰인다.
Agglomerative, Divisive
3)Density-based Clustering
다양한 모양으로 군집되어지며, 노이즈가 있는 데이터셋에 쓰인다.
DBSCAN
K-means clustering
-partitioning clustering
-K-means divides the data into non-overlapping subsets without any cluster-internal structure
-examples within a cluster are very similar
-examples across different clusters are very idfferent
K-means 안의 sample들은 여러 개의 집단에 속해있다.
집단 내는 동질, 집단 간은 이질적인 특징이 있다.
집단 내의 sample들의 거리는 상호 가까울 수록, 집단 간의 거리는 멀 수록 군집이 잘 되었다고 본다.
어떻게 거리를 측정할까?
-유클리드 거리
- cosine 유사도
-평균거리
등등이 있다. 데이터셋에 대한 이해와 피처의 데이터타입 등에 따라 적절한 측정을 한다.
어떻게 작동할까?
1) initialize k = 3( k는 cluster의 수이다)
centroids : randomly set
2)distance calculation
각 데이터에서 각 centroid까지 거리를 구한다.
3)assign each point to the closest centroid
각 데이터는 가장 가까운 거리에 위치한 centroid에 할당한다.
여기서 SSE를 측정해보면, 오류가 매우 높게 나온다. 왜냐면 centroid를 임의로 정했기 때문에 당연하다.
이 오류를 줄이기 위해서 다음 스텝을 진행한다.
4)compute the new centroids for each cluster
각 centroid에 속한 데이터들의 평균으로 각 centroid는 이동한다.
5) repeat until there are no changes
centroid가 더이상 움직이지 않을 때까지 진행한다.
평가?
만들어진 K-means algorithm이 좋은지 확인하는 척도로 accuracy를 쓴다.
비지도 학습이기 때문에 이전의 알고리즘처럼 단순 계산을 할 수는 없다.
대신에 거리를 가지고 정확도를 측정한다.
아래의 그래프를 보면 k개수가 늘어남에 따라 중심점과 데이터 간의 거리가 좁아지는 것을 볼 수 있다.
그런데 k개수에 따라 데이터 간 거리는 늘 좁아지므로, 급격한 엘보 포인트를 찾으면 되고, 그 수가 얻고자 하는 k값이라고 본다.
임의 데이터 생성하여 k-means 연습하기
import random
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
%matplotlib inline
#1. 데이터 준비하기
#need to set a random seed.
np.random.seed(0)
#make_blobs
X, y = make_blobs(n_samples=5000, centers=[[4,4], [-2, -1], [2, -3], [1, 1]], cluster_std=0.9)
#시각화
plt.scatter(X[:, 0], X[:, 1], marker='.')
#2. K-means 모델링하기
k_means = KMeans(init = "k-means++", n_clusters = 4, n_init = 12)
k_means.fit(X)
k_means_labels = k_means.labels_
k_means_labels
k_means_cluster_centers = k_means.cluster_centers_
k_means_cluster_centers
#visualization
fig = plt.figure(figsize=(6, 4))
colors = plt.cm.Spectral(np.linspace(0, 1, len(set(k_means_labels))))
ax = fig.add_subplot(1, 1, 1)
for k, col in zip(range(len([[4,4], [-2, -1], [2, -3], [1, 1]])), colors):
# Create a list of all data points, where the data points that are
# in the cluster (ex. cluster 0) are labeled as true, else they are
# labeled as false.
my_members = (k_means_labels == k)
# Define the centroid, or cluster center.
cluster_center = k_means_cluster_centers[k]
# Plots the datapoints with color col.
ax.plot(X[my_members, 0], X[my_members, 1], 'w', markerfacecolor=col, marker='.')
# Plots the centroids with specified color, but with a darker outline
ax.plot(cluster_center[0], cluster_center[1], 'o', markerfacecolor=col, markeredgecolor='k', markersize=6)
ax.set_title('KMeans')
ax.set_xticks(())
ax.set_yticks(())
plt.show()
실제 데이터로 연습하기
import pandas as pd
cust_df = pd.read_csv("Cust_Segmentation.csv")
cust_df.head()
#categorical한 데이터는 삭제하기
df = cust_df.drop('Address', axis=1)
df.head()
#데이터 정규화, 표준화하기
from sklearn.preprocessing import StandardScaler
X = df.values[:,1:]
X = np.nan_to_num(X)
Clus_dataSet = StandardScaler().fit_transform(X)
Clus_dataSet
#모델링
clusterNum = 3
k_means = KMeans(init = "k-means++", n_clusters = clusterNum, n_init = 12)
k_means.fit(X)
labels = k_means.labels_
print(labels)
#insight 얻기
df["Clus_km"] = labels
df.head(5)
df.groupby('Clus_km').mean()
#2차원 시각화
area = np.pi * ( X[:, 1])**2
plt.scatter(X[:, 0], X[:, 3], s=area, c=labels.astype(np.float), alpha=0.5)
plt.xlabel('Age', fontsize=18)
plt.ylabel('Income', fontsize=16)
plt.show()
#3차원 시각화
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(1, figsize=(8, 6))
plt.clf()
ax = Axes3D(fig, rect=[0, 0, .95, 1], elev=48, azim=134)
plt.cla()
# plt.ylabel('Age', fontsize=18)
# plt.xlabel('Income', fontsize=16)
# plt.zlabel('Education', fontsize=16)
ax.set_xlabel('Education')
ax.set_ylabel('Age')
ax.set_zlabel('Income')
ax.scatter(X[:, 1], X[:, 0], X[:, 3], c= labels.astype(np.float))