코딩일기

[DataScience] 머신러닝, k means clustering( feat. just go ) 본문

Code/머신러닝(ML)

[DataScience] 머신러닝, k means clustering( feat. just go )

daje 2021. 1. 18. 19:51
728x90
반응형

저 앞에는 아직 구름이지만, 이 앞은 보이네

 

안녕하십니까 다제입니다. 

 

오느은 선형 회귀의 clustering에 대해서 알아보도록 하겠습니다. 

 

머신러닝 공부를 위해 맨처음 시작되는 글에 아래와 같은 도표를 보여드린 적이 있습니다. 

 

 

앞에서 배운 차원축소는 지도학습에 해당됩니다. 

이제 비지도학습의 대표주자인 k-means clustering에 대해 알아보도록 하겠습니다. 

 

k-means clustering 요약 그림 (출처 : http://stanford.edu/~cpiech/cs221/img/kmeansViz.png)

 

(a) -> (f)로 갈수록 그룹화가 되어가는 모습을 보실 수 있습니다. 

k-means clustering은 정답이 없는데 컴퓨터 혼자서 학습을 하면서 위와 같이 비슷한 그룹이라 판단되는 것끼리 

그룹화를 하는 메소드 입니다. 

 

Clustering의 목적

위에서도 언급하였듯 Clustering이 대답할수 있는 질문은 주어진 데이터들이 얼마나, 어떻게 유사한지 입니다.

그렇기 때문에 주어진 데이터셋을 요약/정리하는데 있어서 매우 효율적인 방법들중 하나로 사용 되고 있습니다.

그러나 동시에 정답을 보장하지 않는다는 이슈가 있어서 production의 수준이나

혹은 예측을 위한 모델링에 쓰이기 보다는 EDA를 위한 방법으로써 많이 쓰입니다.

 

자! 여기에서 어떻게 저게 가능해요? 설명해주세요 라고 하면 

솔직히 말씀드려서 전 수학적으로 설명할 수 없습니다. ( 저의 부족함을 인정합니다... )

 

그러나, 코드를 어떻게 치고 어떤 변수들을 조작하면 적용할 수 있나요?에 대한 질문은 

아래와 같이 안내드리겠습니다. 

# k-means clustering 진행 
kmeans = KMeans(n_clusters = 3).fit(points)
labels = kmeans.labels_

# 새로 생성된 labels 시리즈 기존 df에 추가 
new_series = pd.Series(labels)
points['clusters'] = new_series.values
points.head()


# 그래프를 그리는 함수 생성
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(points, column_header):
  new_centroids = points.groupby(column_header).mean()
  return new_centroids


centroids = get_centroids(points, 'clusters')
plot_clusters(points, 'clusters', centroids)

 

 

 

 

위 처럼 코드를 작성하여 실행하시면 k(clustering 그룹 수)가 3개로 나누어진 데이터를 보실 수 있습니다. 

음~ 왠지 4개의 clustering으로 나누어야 할것 같다는 생각이 저만 드는건 아니겠죠?

그런데 이를 4개로 나누는 것이 좋은건지를 판단할 기준이 무엇일까요?

 

 

 

여기에서도 고유값이 사용됩니다. 

그래프가 갑자기 변하는 지점의 수를 clustering의 k값으로 넘겨주면 됩니다. 

 

sum_of_squared_distances = []
K = range(1, 15)
for k in K:
    km = KMeans(n_clusters = k)
    km = km.fit(points)
    sum_of_squared_distances.append(km.inertia_)

plt.plot(K, sum_of_squared_distances, 'bx-')
plt.xlabel('k')
plt.ylabel('Sum_of_squared_distances')
plt.title('Elbow Method For Optimal k')
plt.show()

 

짠! 4에서 갑자기 그래프의 기울기가 급격하게 변하는 걸 보실 수 있습니다. 

아 그럼! 4개로 나누는게 맞구나~ 라고 인지하시고 다시 실행보면 아래와 같은 그림을 얻을 수 있습니다. 

 

 

예제 코드는 아직 정확히 다 만들진 못하였습니다............ 저에겐 시간이 너무 부족하다는.....

 

생명을 갈아넣고 있지만.. 아직 만족할만한 자료들이 툭툭 튀어나오지 않네요

 

가지고 있으신 데이터를 가지고도 충분히 실습하실 수 있으니 꼭 테스트를 진행해보시는걸 추천드립니다. 

 

궁금하신 사항은 언제든 연락부탁드립니다. 

 

감사합니다. 

728x90
반응형
Comments