상세 컨텐츠

본문 제목

[Machine Learning - 머신러닝]K-평균(K-means) 알고리즘 소스 구현

Artificial Intelligence

by [성운] 2019. 9. 10. 21:39

본문

이차원 좌표에 2000개 데이터를 랜덤으로 생성해서 4개의 군집으로 그룹화하는 K-평균 알고리즘을 구현하겠습니다. 선행학습으로 https://ynebula.tistory.com/39군집화 및 K-평균이 필요합니다.

 

학습데이터 생성

Souce-1

학습데이터를 생성합니다X, Y 좌표에 np.random.normal() 함수를 이용해서 정규분포에 맞게 생성합니다np.random.normal(0.0, 0.9)는 평균은 0.0이고 편차가 0.9인 수를 랜덤하게 리턴합니다.

 

Source-2

X, Y 좌표 데이터를 저장한 리스트 변수 vector_setPandas DataFrame() 함수를 이용해 2차원 데이터프레임 자료구조를 생성합니다파이썬의 그래픽 라이브러리에서 matplotlib을 기반으로 하는 seaborn 시각화 패키지를 이용해서 시각화로 표현하여 데이터프레임 데이터를 확인합니다.

학습 데이터 분포

학습시작

Source-3

모든 학습 데이터를 텐서에 할당합니다. 4개의 그룹으로 그룹핑할 것이므로 K4로 합니다. 또한 K-Means 알고리즘의 초기 중심은 임의의 좌표로 설정해야 합니다. random_shuffle() 함수를 이용해서 vectors를 무작위로 섞은 다음 4개의 초기 중심을 선택합니다.

Source-4

두 텐서의 형태를 확인하면 vectors20002, centroides42열을 확인할 수 있습니다.

이젠 유클리디안 연산을 수행하여 가장 가까운 중심점을 찾아 클러스터링을 수행해야 합니다. 연산을 수행하기 위해서는 vectorscentroides는 동일한 크기여야만 합니다. 크기를 맞추기 위해 두 텐서를 expanded_vectors, expanded_centroides로 차원을 확장합니다.

vectors에서 D0에 차원에 크기 1을 추가해서 expanded_vectors를 만듭니다. centroides에서 D0에 차원에 크기 1을 추가해서 expanded_centroides를 만듭니다.

텐서플로는 1인 차원은 연산 시 다른 텐서의 해당 차원 크기에 맞게 계산을 반복하는 브로드캐스팅을 지원합니다.

각 데이터에 대해 유클리디안 연산을 수행해 가장 가까운 중심점에 클러스터링 합니다.

 

중심점 업데이트

Source-5

K개 군집에 속하는 점들의 평균을 가진 K개의 텐서를 합쳐서(concatenate) mean 텐서를 만듭니다.

equal 함수를 사용하여 한 군집과 매칭되는 assignments 텐서의 각 원소 위치를 True로 표시하는 불리언 텐서(Dimension(2000))를 만듭니다.

군집의 번호를 변수 C에 매핑합니다.

where 함수를 사용하여 매개변수로 받은 불리언 텐서에서 True로 표시된 위치를 값으로 가지는 텐서(Dimension(2000)*Dimension(1))를 만듭니다.

, 중간에 코드로 구조를 확인해보면 세션 실행 전이므로 차원의 크기가 결정되지 않아 Dimension(2000) 대신 Dimension(None)으로 나옵니다.

reshape함수를 사용하여 c군집에 속한 vectors 텐서의 포인트들의 인덱스로 구성된 텐서(Dimension(2000)*Dimension(2))를 만듭니다.

gather 함수를 사용하여 c 군집을 이루는 점들의 좌표를 모은 텐서(Dimension(1)*Dimension(2000)*Dimension(2))를 만듭니다.

reduce_mean 함수를 사용하여 c 군집에 속한 모든 점의 평균 값을 가진 텐서 (Dimension(1)*Dimenstion(2))를 만듭니다.

 

그래프 실행

Source-6

데이터 그래프를 실행하기 전에 tf.global_variables_initializer()를 수해하여 모든 변수를 초기화합니다. 매 반복마다 중심점은 업데이트되고 각 점은 새 군집에 할당됩니다.

이 코드에서 매개변수로 지정한 세 개의 연산은 run() 함수를 호출하면 지정한 순서대로 실행됩니다. 찾아야 할 값이 세 개이므로 sess.run()은 훈련 과정 동안 세 개의 연산에 상응하는 텐서 세 개를 numpy 배열 타입으로 리턴 합니다.

update_centroides 연산은 리턴 값이 없으므로 _(밑줄)을 사용해 결과를 버리게 했습니다.

(사실 _도 다른 변수와 똑같이 변수이지만, 파이썬 사용자들은 결과를 버릴 때 _을 사용하는 것이 관습입니다.)

 

assignment_values 텐서의 결과를 확인해 보기 위해 다음 코드를 작성합니다.

Source-7

 

K-Means 분포 결과

Source

https://github.com/ynebula/First-Contact-with-Books/blob/master/Tensorflow/K_Means.ipynb

 

ynebula/First-Contact-with-Books

첫걸음 시리즈 예제 소스입니다. Contribute to ynebula/First-Contact-with-Books development by creating an account on GitHub.

github.com

 

글이 도움이 되셨다면 공감 부탁 드립니다.

감사합니다.

 

[References]

Tensorflow 첫걸음

관련글 더보기

댓글 영역