silhouette_score

jh_k·2023년 2월 24일
0

비지도학습

목록 보기
6/6

sklearn.metrics.silhouette_score

sklearn.metrics.silhouettescore(_X, labels, *, metric='euclidean', sample_size=None, random_state=None, **kwds)[source]

실루엣 분석 metirc 값을 구하기 위해 iris데이터를 통하여 실습해 보겠습니다.
이때 군집화는 kmeans 방법으로 클러스터개수를 3개로 수행 하였습니다.

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

iris = load_iris()
feature_names = ['sepal_lenght','sepal_width','petal_length','petal_width']
iris_df = pd.DataFrame(iris.data,columns=feature_names)

## kmeans 군집화 수행
kmeans = KMeans(n_clusters=3,init='k-means++',max_iter=100,random_state=0).fit(iris_df)
iris_df['cluster'] = kmeans.labels_
iris_df.head()
sepal_lenght	sepal_width	petal_length	petal_width	cluster
0	5.1				3.5			1.4				0.2			1
1	4.9				3.0			1.4				0.2			1
2	4.7				3.2			1.3				0.2			1
3	4.6				3.1			1.5				0.2			1
4	5.0				3.6			1.4				0.2			1
# iris 의 모든 개별 데이터에 실루엣 계수값을 구함
score_samples = silhouette_samples(iris.data,iris_df['cluster'])
print('silhouette_sample() return 값의 shape',score_samples.shape)

# 실루엣 계수 컬럼 추가
iris_df['silhouette_coeff'] = score_samples

# 모든 데이터의 평군 실루엣 계수값을 구함
average_score = silhouette_score(iris.data,iris_df['cluster'])
print('평균 실루엣 값',average_score)


iris_df.groupby('cluster')['silhouette_coeff'].mean()

silhouette_sample() return 값의 shape (150,)
평균 실루엣 값 0.5528190123564095
cluster
0 0.417320
1 0.798140
2 0.451105

데이터 별 실루엣 계수
클러스터가 1인 데이터들은 0.8 정도의 실루엣 계수를 가지므로
군집화가 어느정도 잘 된 듯하다.
하지만 실루엣 계수 평균 값이 0.553인 이유는
다른 클러스터에 할당된 데이터들의 실루엣 계수값이 작아서이다

## 실루엣 계수 시각화를 통하여 최적의 클러스터수 찾기

# 실루엣 기법
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="--")
from sklearn.datasets import make_blobs
x,y = make_blobs(n_samples=500,n_features=2,centers=4,cluster_std=1,
                center_box=(-10,10),shuffle=True,random_state=1)

visualize_silhouette([2,3,4,5],x)

실루엣 계수는 클러스터 2일때 좋은 값이 나왓지만
데이터의 분포가 고르지 않기 때문에
클러스터 4로 했을때 데이터의 분포가 고르고 실루엣 계수값도 좋게 나왓다

profile
Just Enjoy Yourself

0개의 댓글