聚类(Clustering): K-means算法
聚類(Clustering): K-means算法
1.歸類:
聚類(clustering)屬于非監督學習(unsupervised learning)
無類別標記( class label)
3. K-means 算法:
3.1 Clustering 中的經典算法,數據挖掘十大經典算法之一
3.2 算法接受參數 k ;然后將事先輸入的n個數據對象劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的對象相似度較高;而不同聚類中的對象相似度較小。(k表示數據要分的類別的數量,比如上圖分為三種類型,則k=3)
3.5 算法流程:
輸入:k, data[n];( k:分的類別數,data[n]:樣本數據)(1) 選擇k個初始中心點,例如c[0]=data[0],…c[k-1]=data[k-1];(通常用random隨機挑選初始中心點)(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]值的變化小于給定閾值。Euclidean Distance歐幾里得距離即求向量之間的距離
概括:1.(隨機)定義三個中心點.2.找最近的點3.用均值定義新的中心點.4.繼續23步直到中心點保持不變/達到預定的次數/分類變化小于預定值
4.流程圖:
示例:
用矩陣計算距離:(不用Euclidean Distance方式計算)
上標0表示第0次迭代,上面一行4個值分別表示與(1,1)的距離值
上下兩排中,1表示對應位置的該點歸為當前相同類,0則表示歸為不同類
Group1的中心點不變(因為只有A一個點)
Group2的中心點為:(求均值)
重新劃分類別:
此時B點被分類為group1:
再分類:
此時,分類相比上次已經沒有變化了:
所以迭代停止
聚類算法優缺點:
優點:速度快,簡單
缺點:最終結果跟初始點選擇相關度很大,容易陷入局部最優,需直到k值
聚類(Clustering): K-means算法應用
Python中code實例應用:
import numpy as np# Function: K Means # ------------- # K-Means is an algorithm that takes in a dataset and a constant # k and returns k centroids (which define clusters of data in the # dataset which are similar to one another).def kmeans(X,k,maxIt): '''X:數據集;k:分類個數;maxIt:設置的循環次數'''numPoints,numDim = X.shape #X(類型為numpy array),行數(也可以叫做點數)和列數(維度)dataSet = np.zeros((numPoints,numDim+1)) #注意這里有兩組括號dataSet[:, :-1] = X #dataset中除了最后一列的值都用X的值替代'''array中直接使用等號這種賦值方法(“=”),必須兩者維度相同,所以這里把最后一列除開在外,使兩者維度相同'''# Initialize centroids randomly#隨機生成初始中心點centroids = dataSet[np.random.randint(numPoints,size=k),:] #需要從所有行中選取k組作為中心點# centroids =dataSet[0:2,:] ##表示自行選取前兩個axis中兩組點作為中心點,用來核算算法是否準確#Randomly assign labels to initial centoridcentroids[:,-1] = range(1,k+1) #將中心點分類為1,2,k~等若干類# Initialize book keeping vars. 記賬:迭代次數iterations = 0oldCentroids = None #每一次迭代完新的中心點就要變成舊的中心點,后面用 # Run the main k-means algorithm # 停止函數中的參數: # oldCentroids: 舊的中心點 # centroids:新的中心點,可以設置新舊相等時停止 # iterations: 記錄循環多少次,可以用來設置到指定循環次數停止 # maxIt:循序循環的最大次數while not shouldStop(oldCentroids,centroids,iterations,maxIt):print('iterations:\n',iterations)print('dataSet:\n',dataSet)print('centroids:\n',centroids)# Save old centroids for convergence test. Book keepingoldCentroids = np.copy(centroids) #將新中心點變為就中心點,并且保留舊中心點的值,**使用np.copy**iterations += 1# Assign labels to each datapoint based on centroidsupdateLabels(dataSet,centroids) #調用更新label的函數centroids = getCentroids(dataSet,k) #獲取中心點用于判斷是否結束# We can also get the labels by calling getLabels(dataSet, centroids)return dataSet# Function: Should Stop # ------------- # Returns True or False if k-means is done. K-means terminates either # because it has run a maximum number of iterations OR the centroids stop changing. # 終止條件:迭代次數到達指定次數;或中心點不再變化 def shouldStop(oldCentroids,centroids,iterations,maxIt):if iterations>maxIt:return Truereturn np.array_equal(oldCentroids,centroids) #**使用np.array_equal判斷兩數組值是否相等**判斷類型相同則用?def updateLabels(dataSet,centroids): #距離中心點最短則與中心點歸為一類,歸類的具體方法后面單獨封包了函數numPoints,numDim = dataSet.shapefor i in range(numPoints):dataSet[i,-1] = getLabelFromClosestCentroids(dataSet[i,:-1],centroids)#需要參數:中心點和每一行的特征值#歸類方法比較復雜,單獨封包一個函數def getLabelFromClosestCentroids(dataRow,centroids): # dataSetRow:一行一個實例。中心點(K行,列數相同的矩陣) label = centroids[0,-1] #第0個[]中的的倒數第一個值賦值給labelminDist = np.linalg.norm(dataRow - centroids[0,:-1]) #第一個距離就是最小值,dataRow?'''np.linalg.norm(X-Y):sqrt((x1-y1)^2+(x2-y2)^2),X=np.array([x1,x2]),Y=np.array([y1,y2]);可以理解為歐幾里得distance求向量的距離'''#linalg=linear(線性)+algebra(代數),norm則表示范數for i in range(1,centroids.shape[0]+1): #+1?dist = np.linalg.norm(dataRow-centroids[i,:-1])if dist < minDist:minDist = distlabel = centroids[i,-1]print('minDist:',minDist)return label # Function: Get Centroids # ------------- # Returns k random centroids, each of dimension n. def getCentroids(dataSet,k):result = np.zeros((k,dataSet.shape[1])) #兩對括號 不然會報錯 TypeError: data type not understoodfor i in range(1,k+1):oneCluster = dataSet[dataSet[:,-1]==i,:-1] #對于dataset每一行如果dataset最后一個值(即label)=i,則把它的特征值X賦值給oneCluster組成一個數組array'''相當于嵌套了一個if dataSet[:-1]==i語句'''# np.meamn,axis=0對array的行求均值,axis=1對array的列求均值result[i-1,:-1] = np.mean(oneCluster,axis=0) #求均值找中心點,result即新的中心點result[i-1,-1] = i #Label分類為ireturn resultx1 = 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:\n',result)#sklearn 中也可以調用kmeans算法總結
以上是生活随笔為你收集整理的聚类(Clustering): K-means算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python程序操作的核心_python
- 下一篇: logistic模型原理与推导过程分析(