본문 바로가기
카테고리 없음

[머신러닝] K-means 알고리즘을 배우기

by 인포메틱스 2024. 5. 27.
반응형

1. Intro

 

 대부분의 머신러닝 알고리즘은 라벨이 있는 데이터를 예측하는데 유용합니다. 이를 Supervised learning (지도 학습)이라고 합니다. 하지만 라벨이 없는 데이터 세트를 처리해야할 때가 많습니다. 이러한 문제는 Unsupervised learning비지도 학습 기법으로 해결할 수 있습니다. K-means 알고리즘은 데이터 세트를  K개의 클러스터로 나누는 비지도 학습 알고리즘입니다. 유사한 방법으로는 KNN방법이 있습니다. 해당 방법은 추후에 설명하도록 하겠습니다.

 

2. K-means 알고리즘의 역활

 

K-means 알고리즘은 데이터를 주어진 클러스터 수로 분할합니다. 각 클러스터 내의 데이터 포인트는 유사하고, 다른 클러스터의 포인트와는 차이가 큽니다. 유사성은 주로 유클리드 거리를 사용해 측정이 됩니다. 알고리즘은 클러스터 내 분산을 최소화하는 방식으로 동작합니다.

 

단계별 설명

1. 초기 중심 선택 : 초기 중심을 무작위로 선택합니다.

2. 각 포인트와 중심간의 거리 계산 : 각 데이터 포인트를 가장 가까운 중심에 할당합니다.

3. 새 중심 계산 및 반복 : 각 클러스터의 새로운 중심을 계산하고, 변화가 없을 때까지 반복합니다.

 

3. 파이썬으로 구현하기

파이썬으로 K-means 알고리즘을 구현하기 위해서 Numpy를 사용합니다. 

 

__init__  기본 파라미터를 초기화합니다.

pick_centers : 초기 중심을 무작위로 선택합니다.

get_closest_centroid : 각 포인트에 가장 가까운 중심을 찾습니다.

create_clusters : 각 포인트를 가장 가까운 중심에 할당하여 클러스터를 만듭니다.

compute_centroids : 각 클러스터의 중심을 계산합니다.

is_converged : 중심이 변화했는지 확인합니다.

fit_predict : 데이터를 학습하고 각 포인트의 클러스터를 예측합니다.

clustering_errors : 최적화의 품질을 평가합니다.(유클리드를 이용하기 때문에 거리 계산 공식을 사용합니다.)

 

import numpy as np

def euclidean_distance(a, b):
    return np.sqrt(np.sum((a - b) ** 2))

class Kmeans:
    def __init__(self, k=3, max_iter=100, tol=1e-06):
        self.k = k
        self.max_iter = max_iter
        self.tol = tol
  
    def pick_centers(self, X):
        centers_idxs = np.random.choice(self.n_samples, self.k)
        return X[centers_idxs]
    
    def get_closest_centroid(self, x, centroids):
        distances = [euclidean_distance(x, centroid) for centroid in centroids]
        return np.argmin(distances)
    
    def create_clusters(self, centroids, X):
        clusters = [[] for _ in range(self.k)]
        labels = np.empty(self.n_samples)
        for i, x in enumerate(X):
            centroid_idx = self.get_closest_centroid(x, centroids)
            clusters[centroid_idx].append(i)
            labels[i] = centroid_idx
        return clusters, labels
    
    def compute_centroids(self, clusters, X):
        centroids = np.empty((self.k, self.n_features))
        for i, cluster in enumerate(clusters):
            centroids[i] = np.mean(X[cluster], axis=0)
        return centroids
    
    def is_converged(self, old_centroids, new_centroids):
        distances = [euclidean_distance(old_centroids[i], new_centroids[i]) for i in range(self.k)]
        return sum(distances) < self.tol

    def fit_predict(self, X):
        self.n_samples, self.n_features = X.shape
        self.centroids = self.pick_centers(X)
        for _ in range(self.max_iter):
            self.clusters, self.labels = self.create_clusters(self.centroids, X)
            new_centroids = self.compute_centroids(self.clusters, X)
            if self.is_converged(self.centroids, new_centroids):
                break
            self.centroids = new_centroids
    
    def clustering_errors(self, X):
        cluster_values = [X[cluster] for cluster in self.clusters]
        squared_distances = []
        for i, cluster_array in enumerate(cluster_values):
            squared_distances.append(np.sum((cluster_array - self.centroids[i]) ** 2))
        return np.sum(squared_distances)

 

 

4. 구현

 

from sklearn.datasets import make_blobs

X, _ = make_blobs(n_samples=500, n_features=2, centers=4, shuffle=False, random_state=0)

model = Kmeans(k=4)
model.fit_predict(X)

 

5. 마무리

 

 사실 sklearn.cluster에 KMeans라는 기능이 있습니다. 이를 통해 쉽게 구현할 수 있습니다. 그러나 이렇게 코드로 실습을 해보면 다른 사람들의 코드 아이디어를 확인할 수가 있고 어떻게 돌아가는지도 같이 알 수도 있습니다.

728x90
반응형

댓글