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라는 기능이 있습니다. 이를 통해 쉽게 구현할 수 있습니다. 그러나 이렇게 코드로 실습을 해보면 다른 사람들의 코드 아이디어를 확인할 수가 있고 어떻게 돌아가는지도 같이 알 수도 있습니다.
댓글