머신러닝/machine learning

clustering, k-means

Olivia-BlackCherry 2023. 5. 18. 22:37

목차

    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))