k-means方法解釋和具體實現
阿新 • • 發佈:2018-10-10
vpd type ros 列數 roi elf 閾值 自動 print k-means方法實現流程:
輸入:k, data[n];
(1) 選擇k個初始中心點,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 對於data[0]….data[n], 分別與c[0]…c[k-1]比較,假定與c[i]差值最少,就標記為i;
(3) 對於所有標記為i點,重新計算c[i]={ 所有標記為i的data[j]之和}/標記為i的個數;
(4) 重復(2)(3),直到所有c[i]值的變化小於給定閾值。
輸入:k, data[n];
(1) 選擇k個初始中心點,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 對於data[0]….data[n], 分別與c[0]…c[k-1]比較,假定與c[i]差值最少,就標記為i;
(3) 對於所有標記為i點,重新計算c[i]={ 所有標記為i的data[j]之和}/標記為i的個數;
(4) 重復(2)(3),直到所有c[i]值的變化小於給定閾值。
k-means方法具體實現和流程:
import numpy as np #X樣本點坐標矩陣 def kmeans(X, k, maxIt): #X.shape:矩陣的形狀,返回值為行和列 numPoints, numDim = X.shape #得到一個比原矩陣多一列的0矩陣 dataSet = np.zeros((numPoints, numDim + 1)) #前面n-1列為點的值 dataSet[:, :-1] = X #Initialize centroids randomls隨機產生初始中心 #中心點為任意一行數據 centroids = dataSet[np.random.randint(numPoints, size=k), :] centroids = dataSet[0:2, :] #為中心點賦予類名稱,range函數的特點是按順序從前往後賦值1到k,但是k+1必須小於列數,復制到k時,後面的值自動為0 centroids[:, -1] = range(1, k + 1) #第一個為存儲叠代次數,第二個存儲舊的中心 iterations = 0 oldCentroids = None while not shouldStop(oldCentroids, centroids, iterations, maxIt): print("iteration: \n", iterations) print("dataSet: \n", dataSet) print("centroids: \n", centroids) #復制一份中心數據,這樣互不影響,引用則不行 oldCentroids = np.copy(centroids) #每進行一次這個程序,叠代次數就增加1次 iterations += 1 #調用方法更新標簽 updateLabels(dataSet, centroids) #調用方法更新中心 centroids = getCentroids(dataSet, k) #We can get the labels too by calling getLabels(dataSet, centroids) return dataSet #結束條件:叠代次數大於設定的次數或者舊的叠代中心和新得到的叠代中心相等 def shouldStop(oldCentroids, centroids, iterations, maxIt): if iterations > maxIt: return True return np.array_equal(oldCentroids, centroids) #Update a label for each piece of data in the dataset. def updateLabels(dataSet, centroids): # For each element in the dataset, chose the closest centroid. #Make that centroid the element‘s label. numPoints, numDim = dataSet.shape #循環獲取每一行數據 for i in range(0, numPoints): #dataSet[i,-1]表示後面每一行數據的分類標簽 dataSet[i, -1] = getLabelFromClosestCentroid(dataSet[i, :-1], centroids) def getLabelFromClosestCentroid(dataSetRow, centroids): label = centroids[0, -1]; #第一行數據與目標的距離定義為最小值 minDist = np.linalg.norm(dataSetRow - centroids[0, :-1]) #依次比較距離,最終得到屬於的標簽 for i in range(1, centroids.shape[0]): dist = np.linalg.norm(dataSetRow - centroids[i, :-1]) if dist < minDist: minDist = dist label = centroids[i, -1] print("minDist:", minDist) return label #Returns k random centroids, each of dimension n. def getCentroids(dataSet, k): result = np.zeros((k, dataSet.shape[1])) #k表示聚類中心個數 for i in range(1, k + 1): print(dataSet) #找出同類型的點,取出樣本點的向量值 oneCluster = dataSet[dataSet[:, -1] == i, :-1] print("--------------------") print(oneCluster) print("-------------------") #通過均值計算中心點 result[i - 1, :-1] = np.mean(oneCluster, axis=0) #給中心點賦標簽值 result[i - 1, -1] = i return result x1 = np.array([1, 1]) x2 = np.array([2, 1]) x3 = np.array([4, 3]) x4 = np.array([5, 4]) testX = np.vstack((x1, x2, x3, x4)) result = kmeans(testX, 2, 10) print("final result:") print(result)
k-means方法解釋和具體實現