실루엣 분석
코드
from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
# 실루엣 분석 metric 값을 구하기 위한 API 추가
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
%matplotlib inline
iris = load_iris()
feature_names = ['sepal_length','sepal_width','petal_length','petal_width']
irisDF = pd.DataFrame(data=iris.data, columns=feature_names)
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300,random_state=0).fit(irisDF)
irisDF['cluster'] = kmeans.labels_
# iris 의 모든 개별 데이터에 실루엣 계수값을 구함.
score_samples = silhouette_samples(iris.data, irisDF['cluster'])
print('silhouette_samples( ) return 값의 shape' , score_samples.shape)
# irisDF에 실루엣 계수 컬럼 추가
irisDF['silhouette_coeff'] = score_samples
# 모든 데이터의 평균 실루엣 계수값을 구함.
average_score = silhouette_score(iris.data, irisDF['cluster'])
print('붓꽃 데이터셋 Silhouette Analysis Score:{0:.3f}'.format(average_score))
print(irisDF.shape)
irisDF.head(3)
irisDF.groupby('cluster')['silhouette_coeff'].mean()
cluster
0 0.417320
1 0.798140
2 0.451105
Name: silhouette_coeff, dtype: float64
irisDF['silhouette_coeff'].hist()
클러스터별 평균 실루엣 계수의 시각화를 통한 클러스터 개수 최적화 방법
### 여러개의 클러스터링 갯수를 List로 입력 받아 각각의 실루엣 계수를 면적으로 시각화한 함수 작성
def visualize_silhouette(cluster_lists, X_features):
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import math
# 입력값으로 클러스터링 갯수들을 리스트로 받아서, 각 갯수별로 클러스터링을 적용하고 실루엣 개수를 구함
n_cols = len(cluster_lists)
# plt.subplots()으로 리스트에 기재된 클러스터링 수만큼의 sub figures를 가지는 axs 생성
fig, axs = plt.subplots(figsize=(4*n_cols, 4), nrows=1, ncols=n_cols)
# 리스트에 기재된 클러스터링 갯수들을 차례로 iteration 수행하면서 실루엣 개수 시각화
for ind, n_cluster in enumerate(cluster_lists):
# KMeans 클러스터링 수행하고, 실루엣 스코어와 개별 데이터의 실루엣 값 계산.
clusterer = KMeans(n_clusters = n_cluster, max_iter=500, random_state=0)
cluster_labels = clusterer.fit_predict(X_features)
sil_avg = silhouette_score(X_features, cluster_labels)
sil_values = silhouette_samples(X_features, cluster_labels)
y_lower = 10
axs[ind].set_title('Number of Cluster : '+ str(n_cluster)+'\\n' \\
'Silhouette Score :' + str(round(sil_avg,3)) )
axs[ind].set_xlabel("The silhouette coefficient values")
axs[ind].set_ylabel("Cluster label")
axs[ind].set_xlim([-0.1, 1])
axs[ind].set_ylim([0, len(X_features) + (n_cluster + 1) * 10])
axs[ind].set_yticks([]) # Clear the yaxis labels / ticks
axs[ind].set_xticks([0, 0.2, 0.4, 0.6, 0.8, 1])
# 클러스터링 갯수별로 fill_betweenx( )형태의 막대 그래프 표현.
for i in range(n_cluster):
ith_cluster_sil_values = sil_values[cluster_labels==i]
ith_cluster_sil_values.sort()
size_cluster_i = ith_cluster_sil_values.shape[0]
y_upper = y_lower + size_cluster_i
color = cm.nipy_spectral(float(i) / n_cluster)
axs[ind].fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_sil_values, \\
facecolor=color, edgecolor=color, alpha=0.7)
axs[ind].text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
y_lower = y_upper + 10
axs[ind].axvline(x=sil_avg, color="red", linestyle="--")
# make_blobs 을 통해 clustering 을 위한 4개의 클러스터 중심의 500개 2차원 데이터 셋 생성
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=500, n_features=2, centers=4, cluster_std=1, \\
center_box=(-10.0, 10.0), shuffle=True, random_state=1)
# cluster 개수를 2개, 3개, 4개, 5개 일때의 클러스터별 실루엣 계수 평균값을 시각화
visualize_silhouette([ 2, 3, 4, 5], X)
from sklearn.datasets import load_iris
iris=load_iris()
visualize_silhouette([ 2, 3, 4,5 ], iris.data)
Mean Shift 군집화 ( GMM, bandwidth를 활용한 KDE )
KDE( Kernel Density Estimation)
확률밀도 추정 방식
비모수적 추정 방식 - 히스토그램
비모수적추정 방식 - KDE
Bandwidth에 따른 KDE 변화
사이킷런을 이용한 Mean Shift
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import MeanShift
X, y = make_blobs(n_samples=200, n_features = 2, centers = 3, cluster_std = 0.7, random_state = 0)
meanshift = MeanShift(bandwidth = 0.8)
cluster_labels = meanshift.fit_predict(X)
print('cluster labels 유형 : ', np,unuque(cluster_labels))
cluster lables 유형 : [ 0 1 2 3 4 5 ]
meanshift = MeanShift(bandwidth = 1) # bandwidth 크기를 1로 변경
cluster_labels = meanshift.fit_predict(X)
print('cluster labels 유형 : ', np,unuque(cluster_labels))
cluster lables 유형 : [ 0 1 2 ]
# 최적값을 찾은 이후에 다시 군집화
from sklearn.cluster import estimate_bandwidth
bandwidth = estimate_bandwidth(X) # 최적의 bandwidth 값 찾기
print('bandwidth 값 : ', round(bandwidth, 3))
bandwidth 값 : 1.816
import pandas as pd
clusterDF - pd.DataFrame(data = X, columns = ['ftr1', 'ftr2'])
clusterDF['target'] = y
import matplotlib.pyplot as plt %matplotlib inline
cluster DF ['meanshift_label'] = cluster_labels
centers = meanshift.cluster_centers_
unique_labels = np.unique(cluster_labels)
markers=['o', 's', '^', 'x', '*']
for label in unique_labels:
label_cluster = cluster DF[cluster DF['meanshift_label'] == label]
center_x_y= centers[label]
# 군집별로 다른 마커로 산점도 적용
plt.scatter(x=label_cluster['ftr1'], y=label_cluster['ftr2'], edgecolor='k', marker-markers[label] )
# 군집별 중심 표현
plt.scatter (x=center_x_y[0], y=center_x_y[1], s=200, color='gray', alpha=0.9, marker-markers[label])
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=70, color='k', edgecolor='k', marker='$%d$' % label)
plt.show()
print(clusterDF.groupby('target')['meanshift_label'].balue_counts())
GMM-거리기반 K-Means의 문제점
GMM 개요
모수 추정을 위한 EM( Expectation and Maximazation)
'빅데이터 분석가 양성과정 > Python - 머신러닝' 카테고리의 다른 글
DBSCAN( Density Based Spatial clustering of application with noise) (0) | 2024.07.12 |
---|---|
군집화 (K-Means) - 실습 (0) | 2024.07.12 |
군집화 (K-Means) (0) | 2024.07.12 |
차원축소(Unsupervised Learning) (3) | 2024.07.12 |
회귀(Regression) - 실습) 자전거 대여 수요 예측 (0) | 2024.07.12 |