import numpy as np
# 歐氏距離計算
def distEclud(x,y):
return np.sqrt(np.sum((x-y)**2)) # 計算歐氏距離
# 爲給定數據集構建一個包含K個隨機質心的集合
def randCent(dataSet,k):
m,n = dataSet.shape
centroids = np.zeros((k,n))
for i in range(k):
index = int(np.random.uniform(0,m))
centroids[i,:] = dataSet[index,:]
return centroids
# k均值聚類
def kmeans_open(dataSet,k):
m = np.shape(dataSet)[0] #行的數目
# 第一列存樣本屬於哪一簇
# 第二列存樣本的到簇的中心點的誤差
clusterAssment = np.mat(np.zeros((m,2)))
clusterChange = True
# 第1步 初始化centroids
centroids = randCent(dataSet,k)
while clusterChange:
clusterChange = False
# 遍歷所有的樣本(行數)
for i in range(m):
minDist = 100000.0
minIndex = -1
# 遍歷所有的質心
#第2步 找出最近的質心
for j in range(k):
# 計算該樣本到質心的歐式距離
distance = distEclud(centroids[j,:],dataSet[i,:])
if distance < minDist:
minDist = distance
minIndex = j
# 第 3 步:更新每一行樣本所屬的簇
if clusterAssment[i,0] != minIndex:
clusterChange = True
clusterAssment[i,:] = minIndex,minDist**2
#第 4 步:更新質心
for j in range(k):
pointsInCluster = dataSet[np.nonzero(clusterAssment[:,0].A == j)[0]] # 獲取簇類所有的點
centroids[j,:] = np.mean(pointsInCluster,axis=0) # 對矩陣的行求均值
return clusterAssment.A[:,0], centroids