K-means clustering


💡k-平均クラスタ(k-meansクラスタ)


これは、
  • で与えられたデータをk個(コア数)クラスタに分割するアルゴリズムである.
    各クラスタには中心(コア)があります.各オブジェクトは最も近い中心に割り当てられ、同じ中心に割り当てられたオブジェクトが集合してクラスタを形成する方法.
  • ▼k-meansクラスタリングプロセス


    1.k値を初期値としてk個のセントロイド(下図3 x)を選択
    2.各データポインタを最も近いコアに割り当てる
    3.コアに割り当てられたすべてのデータポイントの中心位置を計算する(コアの再調整)
    4.再調整されたセントロイドに最も近いデータポイントを指定
  • クラスタに有意な変化がないまで、この手順を繰り返します(最適化後).

  • k-meansでkを決定する方法

  • The Eyeball Method:人が目で見て任意指定を判断する方法
  • Metrics:客観的な指標を通じて最適化されたkをどのように選択するか
    Ex)
    Hierarchicalクラスタの可視化Dendrgramを利用して、
    The Elbowメソッド(:scree plot)を使用して、
    The Silhouette Method
  • 📖 Pythonの例


    pythonを使用してk-meansクラスタを練習する
  • データを準備し、plotで
  • を表す.
    import pandas as pd
    import matplotlib.pyplot as plt
    from sklearn.datasets import make_blobs
    
    x, y = make_blobs(n_samples = 100, centers = 3, n_features = 2)
    
    # make_blobs 함수?
    # 등방성 가우시안 정규분포를 이용해 가상 데이터를 생성하는 함수 
    # (보통 클러스링 용 가상데이터를 생성하는데 사용)
    '''
    parameter
    n_samples : 표본 데이터의 수, 디폴트 100
    n_features : 독립 변수의 수, 디폴트 20
    centers : 생성할 클러스터의 수 혹은 중심, [n_centers, n_features] 크기의 배열. 디폴트 3
    cluster_std: 클러스터의 표준 편차, 디폴트 1.0
    center_box: 생성할 클러스터의 바운딩 박스(bounding box), 디폴트 (-10.0, 10.0))
    
    return:
    X : [n_samples, n_features] 크기의 배열, 독립 변수
        (즉, 데이터 포인터의 위치, cluster가 표현된 것)
    y : [n_samples] 크기의 배열, 종속 변수
        (x로 인해 cluster 별로 나누어진 integer 값)
    '''
    
    df = pd.DataFrame(dict(dx = x[:, 0], y = x[:, 1], label = y))
    
    colors = {0 : 'pink', 1 : 'darkorange', 2 : 'teal'}
    fig, ax = plt.subplots()
    grouped = df.groupby('label')
    
    for key, group in grouped:
        group.plot(ax = ax, kind = 'scatter',
        		   x = 'x', y = 'y', label = key, color = colors[key])
    plt.show()   
    
  • ラベルを削除した後、データポインタを使用して図面
  • を確認します.
    data_points = df.drop('label', axis = 1)
    
    plt.scatter(data_points.x, data_points.y)
    plt.show()

    計算
  • 中心点(コア)
  • # centroid 계산
    dataset_centroid_x = data_points.x.mean()
    dataset_centroid_y = data_points.y.mean()
    
    # print(dataset_centroid_x, dataset_centroid_y) 
    #    = -0.5316497686409459, -3.8350266662423365
    
    # centroid plot으로 표현
    ax.plot(data_points.x, data_points.y)            # (-0.5, -3.8) 표시
    ax = plt.subplot()
    ax.scatter(data_points.x, data_points.y)
    ax.plot(dataset_centroid_x, dataset_centroid_y, "oy")
    plt.show()
  • ランダムポイントを仮想クラスタの中心点
  • として指定する.
    # k-means with 3 cluster. 3개의 sample centroid 설정
    centroids = data_points.sample(3)
    
    # plot 표현
    ax = plt.subplot()
    ax.scatter(data_points.x, data_points.y)
    ax.plot(centroids.iloc[0].x, centroids.iloc[0].y, "or")
    ax.plot(centroids.iloc[1].x, centroids.iloc[1].y, "oc")
    ax.plot(centroids.iloc[2].x, centroids.iloc[2].y, "oy")
    plt.show()
  • セントロイド調整
  • import math
    import numpy as np
    from scipy.spatial import distance
    
    def find_nearest_centroid(df, centroids, iteration):
     
      # 포인트와 centroid 간의 거리 계산
      distances = distance.cdist(df, centroids, 'euclidean')
      
      # 제일 근접한 centroid 선택
      nearest_centroids = np.argmin(distances, axis = 1)
        
      # cluster 할당
      se = pd.Series(nearest_centroids)
      df['cluster_' + iteration] = se.values
      
      return df
    
    
    def plot_clusters(df, column_header, centroids):
      colors = {0 : 'red', 1 : 'cyan', 2 : 'yellow'}
      fig, ax = plt.subplots()
      ax.plot(centroids.iloc[0].x, centroids.iloc[0].y, "ok") # 기존 중심점
      ax.plot(centroids.iloc[1].x, centroids.iloc[1].y, "ok")
      ax.plot(centroids.iloc[2].x, centroids.iloc[2].y, "ok")
      grouped = df.groupby(column_header)
      for key, group in grouped:
          group.plot(ax = ax, kind = 'scatter',
           			 x = 'x', y = 'y', label = key, color = colors[key])
      plt.show()
      
    
    def get_centroids(df, column_header):
      new_centroids = df.groupby(column_header).mean()
      return new_centroids

    明らかな差がないまで重心を何度も再調整した.
    上記の関数は詳細に説明されず、ライブラリで実装できるため、これらの関数のみが記録されます.
    k-means with skckit-learn
    import pandas as pd
    import matplotlib.pyplot as plt
    from sklearn.datasets import make_blobs
    from sklearn.cluster import KMeans 
    
    # random data 생성
    x, y = make_blobs(n_samples = 100, centers = 3, n_features = 2)
    df = pd.DataFrame(dict(x = x[:, 0], y = x[:, 1], label = y))
    
    # k-means clustering
    kmeans = KMeans(n_clusters = 3)        # k=3 
    kmeans.fit(x)                          # clustering 수행
    labels = kmeans.predict(x)                # labels 변수 선언
    
    
    # clustering 결과를 시각화
    x = df.iloc[:, 0].values
    y = df.iloc[:, 1].values
    colors = np.array([0, 10, 20])
    plt.scatter(x, y, c=y, alpha=0.5)

    Elbow methods
    sum_of_squared_distances = []
    K = range(1, 15)
    for k in K:
        km = KMeans(n_clusters = k)
        km = km.fit(df)
        sum_of_squared_distances.append(km.inertia_)
       
    # 시각화
    plt.plot(K, sum_of_squared_distances, 'ro-')
    plt.xlabel('k')
    plt.ylabel('Sum_of_squared_distances')
    plt.title('Elbow Method For Optimal k')
    plt.show()