-about steps...
1. prepare data(vectors)
2. decide how many clusters I need -> group_num(k)
3. choose initial center of cluster(=centroid)
랜덤으로 지정해서 배열에 담고 np로 설정해주기
4. assign data point to nearest cluster
**여기서 5번 과정까지..진짜 한참 헤맸다... 가장 어려웠던 스텝
initial center를 제외한 데이터들의 거리를 비교한다. 가장 가까운 centroid 값의 cluster에 data 지정한다.
5. move centroid to the center of its cluster
data point & cluster point가 움직였으니까 다시 iteration.
6. repeat 4&5... until there is no assigned cluster change
k-means algorithm
<필요한 메소드>
1. 거리 euclidean_distance
2. 최소 거리 구하기
3. clustering하는 메소드
4. 랜덤으로 센터값 설정하고 반복문 돌려서 최소 거리값을 지닌 요소의 인덱스 넣어주기
5. 언제 iteration 멈춰? updated_center_value가 더 이상 안 움직일 때,
즉 center(old)와 updated_center_value(new)사이의 거리 distance = 0,
k개의 2distance의 sum = 0.
*은근 복병인 부분... 벡터 입력 받기. 교수님이 준 입력값으로 쓰일 벡터들의 요소는 모두 공백으로 구분되어있었다. 만약 input()을 사용해서 벡터를 받는다면 data type은 string이 될 것이고 거리를 계산까지 해야되는 나한테는 여기서 치명적인 오류가 생긴다. 처음에는 입력 받지 않고 아래와 같이 직접 타이핑해서 벡터를 써보았다.
import numpy as np
vec_num = 10 # 입력 받을 벡터, 즉 데이터 개수.
data = [[0,0,0,0,0], [0,0,0,0,1], [0, 0, 0, 0, 2], [0, 0, 0, 0, 3]
,[0, 0, 0, 0, 4], [0, 0, 0, 0, 5], [0, 0, 0, 0, 6], [0, 0, 0, 0, 7]
,[0, 0, 0, 0, 8], [0, 0, 0, 0, 9]]
vec_list = np.array(data)
group_num = 3
max_iter_num = 10
#print(vec_list)
#print(vec_list.shape)
def distance(a, b):
return np.sqrt(np.sum(np.square(a-b)))
def find_center(c):
c = np.array(c)
return c.mean(axis=0)
def clustering(v, k, max_iter):
centers = v[np.random.choice(len(v), size=k, replace=False)]
print(centers)
for iteration in range(max_iter):
cluster = {}
for i in range(k):
cluster[i] = []
for vec in v:
tmp = []
for i in range(k):
#print(distance(centers[i], v[vec]))
tmp.append(distance(centers[i], vec))
cluster[np.argmin(tmp)].append(vec)
#cluster_num = len(cluster[i] for i in range(k))
#return cluster_num
updated_center_value = []
for i in range(k):
updated_center_value.append(find_center(v[i]))
updated_center_value = np.array(updated_center_value)
#print(updated_center_value)
if np.sum(centers - updated_center_value) == 0:
representatives = updated_center_value
#return representatives
break
else:
centers = updated_center_value
return iteration
print(clustering(vec_list, group_num, max_iter_num))
교수가 준 또 다른 데이터의 개수는 10000개가 넘었는데 그 많은 것들을 내가 하나하나 타이핑 치는 것은 불가능...
어떻게든 입력 받아야겠다고 맘먹고 이것저것 찾아보고 생각해보다가 np.array([input().strip().split() for _ in range(vec_num)] ,int) 얘로 속 시원하게 성공함. 계속 자바나 C, 혹은 리눅스 같은 것들로만 공부해서 그런지 파이썬이랑은 안 친하다... 메소드만 좀 더 알았더라도 이렇게 쌩고생은 안했을텐데... ㄱ- 일단 클러스터링을 plotting 해본 것도 처음이고 이해하고 구현하기까지 꽤..가 아니라 겁나게 어려웠던 알고리즘........ 심지어 넘파이 관련해서도 모르는게 너무 많다. 구글링 실력 쭉쭉 올라가네..ㅋㅋ 요번에 넘파이 처음 써보는 거라서 그런지 아직 미숙하고... 선대수 잘 몰랐을 때는 (지금도 모르긴 하지만 아예 몰랐을 때) 얼핏 게임 개발 쪽으로 가장 많이 쓰인다는 말을 들었는데 아닌 듯.. 알고보니 데이터 분석이나 인공지능 딥러닝에 필수여따... 나는 아직 어느쪽으로 갈지 결정두 못했는데 말야... 갈 길이 멀군아.
import numpy as np
import sys
sys.stdin = (open('input.txt'))
vec_num = int(input()) # 입력 받을 벡터, 즉 데이터 개수.
data = []
vec_list = np.array([input().strip().split() for _ in range(vec_num)],int)
#print(vec_list)
group_num = int(input())
max_iter_num = int(input())
representatives = []
vec_of_cluster = []
def distance(a, b):
return np.sqrt(np.sum(np.square(a-b)))
def find_center(c):
c = np.array(c)
return c.mean()
def clustering(v, k, max_iter):
centers = v[np.random.choice(len(v), size=k, replace=False)]
print(centers)
print(centers[1])
for iteration in range(max_iter):
cluster = {}
for i in range(k):
count = 0
cluster[i] = []
for vec in range(len(v)):
tmp = []
for i in range(k):
tmp.append(distance(centers[i], v[vec]))
count+=1
vec_of_cluster.append(count)
cluster[np.argmin(tmp)].append(v[vec])
updated_center_value = []
for i in range(k):
updated_center_value.append(find_center(v[i]))
updated_center_value = np.array(updated_center_value)
if np.sum(centers - updated_center_value) == 0:
representative = updated_center_value
representatives.append(representative)
break
else:
centers = updated_center_value
return iteration
print("# of actual iterations: ", clustering(vec_list, group_num, max_iter_num))
print("representatives: " , representatives)
for i in range(vec_num):
print("# of vectors for cluster %d = %d", i, vec_of_cluster[i])
'Major > Linear Algebra' 카테고리의 다른 글
Matrices,Matrix-vector multiplication,Numpy with python (0) | 2022.04.15 |
---|---|
Vector with python 01 (0) | 2022.03.08 |
Vector notation & operations & my proof (0) | 2022.03.03 |