본문 바로가기
머신러닝

[머신러닝] K-Means Clustering

by eyoo 2022. 5. 9.

클러스터링은 Unsupervised Learning이다.

 

kmeans 클러스터링은 랜덤한곳에 점 두개를 찍어 점사이를 기준으로 수직이등분하여 영역을 나눈다. (클러스터링)

구분된 영역의 중앙으로 점들을 이동시키며 다시 수직이등분하여 영역을 나누는 작업을 반복하여

나눈 영역안에 다른 카테고리가 더이상 나타나지 않으면 작업을 끝낸다.

 

 

 

 

 

클러스터링은 k 개의 그룹을 만드는데 3개 이상의 클러스터링을 위해 위의 작업을 반복할때 

사용자가 원치 않는 그룹이 될수있다.

 

 

 

위와 같은 문제는 해결한것이, K-Means++ 알고리즘이다.

K-Means++는 WCSS(within-cluster sums of squares)를 구해 그룹화 작업을 한다.

 

# 센터가 원소들과의 거리가 멀수록 값이 커진다.

# 최소값에 가까워지는 갯수를 뽑되, 갯수가 너무 많아지면 차별성이 없어진다.

# WCSS는 점을 중심으로 각 데이터들의 거리간의 길이를 제곱하여 모두 더한 값이다.

 

 

df=

 

X값을 정한다.

 

X = df.iloc[: , 3:]

 

 

클러스터링은 unsupervised learning이기에 y를 설정할수 없다.

 

KMeans를 설정하기전에 먼저 scatterplot으로 시각화된 데이터의 관계를 보자.

 

in:

sb.scatterplot(data= df, x = 'Annual Income (k$)', y = 'Spending Score (1-100)')
plt.show()

out:

# 사람의 눈으로 볼때는 5개의 그룹이 적당할것 같다.

 

 

하지만 컴퓨터는 엘보우 메소드를 통해 적절한 그룹의 개수를 유추할수 있다.

 

엘보우 메소드는 WCSS값과 그룹의 개수의 관계를 나타내 적절한 그룹개수(k)를 찾을수있다.

 

 

반복문과 kmeans.inertia_를 활용하여 적절한 그룹개수를 찾아보자

 

in:

wcss = []
for k in range(2,11):
    kmeans = KMeans(n_clusters= k, random_state=42)
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)
wcss

out:

[181363.59595959607,
 106348.37306211119,
 73679.78903948837,
 44448.45544793369,
 37233.81451071002,
 30259.657207285458,
 25011.839349156595,
 21850.16528258562,
 19672.07284901432]

# 그룹 개수에 따라 달라지는 wcss값을 볼수있다.

 

 

이를 차트에 나타내 엘보우메소드를 표현해보자

 

in:

plt.plot(range(2,11),wcss)
plt.title('The Elbow Method')
plt.xlabel('Number of Clusters')
plt.ylabel('WCSS')
plt.show()

out:

# 이제 사용자가 엘보우 메소드를 보고 그룹개수를 정해야 한다.

# 그래프가 완만해지기 시작하는 '5개'가 적당해 보인다.

 

 

Kmeans를 그룹개수 5개로 설정하여 모델링한다.

 

 

kmeans = KMeans(n_clusters= 5 , random_state= 42)

 

 

 

결과값을 그룹 컬럼으로 만들어 데이터프레임에 추가한다.

 

in:

y_pred = kmeans.fit_predict(X)
df['Group'] = y_pred
df

out:

 

 

분류된 그룹을 다른색상으로 표현한 차트를 참고하자

 

in:

plt.figure(figsize=[12,8])
plt.scatter(X.values[y_pred == 0, 0], X.values[y_pred == 0, 1], s = 100, c = 'red', label = 'Cluster 1')
plt.scatter(X.values[y_pred == 1, 0], X.values[y_pred == 1, 1], s = 100, c = 'blue', label = 'Cluster 2')
plt.scatter(X.values[y_pred == 2, 0], X.values[y_pred == 2, 1], s = 100, c = 'green', label = 'Cluster 3')
plt.scatter(X.values[y_pred == 3, 0], X.values[y_pred == 3, 1], s = 100, c = 'cyan', label = 'Cluster 4')
plt.scatter(X.values[y_pred == 4, 0], X.values[y_pred == 4, 1], s = 100, c = 'magenta', label = 'Cluster 5')
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s = 300, c = 'yellow', label = 'Centroids')
plt.title('Clusters of customers')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()​

out:

 

 

 

 

 

댓글