1. 程式人生 > >《機器學習實戰》KMeans均值聚類演算法

《機器學習實戰》KMeans均值聚類演算法

一、引言

聚類是一種無監督學習,對一些沒有標籤的資料進行分類。

二、K均值聚類演算法

2.1 演算法過程:

隨機確定K個初始點為質心(簇個數k由使用者給定),計算資料集中每個點到每個質心的距離

本次採用的是歐式距離,

然後將資料集中的每個點尋找距其最近的質心,分配到對應的簇中

完成後,每個簇的質心更新為該簇所有點的平均值。

進行迭代,直到相鄰結果得到最終的質心誤差在允許範圍內。

2.2 對testSet.txt進行資料視覺化:


2.3 聚類結果(K=4):+表示聚類中心點


2.4 後處理提高聚類效能

K是一個使用者預先定義的引數,但我們並不清楚K的選擇是否正確,也不知道這樣生成的簇是否是最好的,如果有比較偏離的一小簇點,也會導致質心偏移,達不到好的聚類效果。
例如在書中10-2的圖中,可以看出點的簇分類結果沒有那麼準確,原因是K均值演算法收斂到了區域性最小,而非全域性最小值。
在包含簇分配結果的矩陣儲存著每個點到簇質心的距離平方值,可以利用該值來評價聚類質量的方法。一類用於度量聚類效果的指標是SSE(誤差平方和),對應我們在clusterAssment矩陣的第一列之和,SSE值越小表明資料點接近於他們的質心,聚類效果越好。

       圖10-2

這裡介紹一下誤差平方和:
物件 誤差的平方和表示為:
引數控制隸屬度的影響.p的值越大,隸屬度影響越大。
由於一個物件可能參與多個簇,所以用隸屬度加權到簇中心的距離之和代表物件擬合聚類的程度。
簇 的SSE是:
聚類C的SSE的定義:,用來度量模糊聚類對資料集合的擬合程度

對圖10-2的優化:

將具有最大SSE的簇劃分為兩個簇,實現時可以將最大簇包含的點過濾出來並在這些點上執行K均值演算法,K=2。

為了保證簇的總數不變,可以將某兩個簇進行合併。

對原圖中即是,將兩個出錯的質心進行合併。

那麼在多維空間中如何合併最近的質心呢?我們可以計算所有質心之間的距離,然後合併距離最近的兩個點來實現,又或者合併兩個簇後計算兩次總SSE值,在所有簇上重複執行,知道找到合併最佳的兩個簇。

2.3 K均值聚類主函式程式

def kMeans(dataSet, k, distMeas=distEclud,createCent=randCent):

    m= shape(dataSet)[0]

   clusterAssment = mat(zeros((m,2)))#create mat to assign data points 

  #儲存每個點的簇分配結果(兩列,儲存簇索引值,儲存誤差(當前點到簇質心的距離))

  centroids = createCent(dataSet, k)

   clusterChanged = True   #標誌變數,true就繼續迭代

   while clusterChanged:

       clusterChanged = False

       for i in range(m):#for each data point assign it to the closest centroid

           minDist = inf; minIndex = -1

           for j in range(k):

                distJI =distMeas(centroids[j,:],dataSet[i,:])

                if distJI < minDist:

                    minDist = distJI; minIndex= j

           if clusterAssment[i,0] != minIndex: clusterChanged = True

           clusterAssment[i,:] = minIndex,minDist**2

       print(centroids)

       for cent in range(k):#recalculate centroids

           ptsInClust = dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]#get allthe point in this cluster

           centroids[cent,:] = mean(ptsInClust, axis=0) #assign centroid to mean

   return centroids, clusterAssment

三、二分K均值演算法

3.1 演算法原理

為了克服K均值收斂於區域性最小值,二分K均值演算法首先將所有點作為一個粗,然後將簇一分為二,之後選擇其中一個簇繼續進行劃分,選擇哪一個簇進行劃分取決於對其劃分是否可以最大程度降低SSE的值,基於SSE的劃分過程不斷重複,直到得到使用者指定的簇數目為止。

3.2 對testSet2.txt資料集進行測試


得到最終的質心結果:centList


畫圖:


得到較好的聚類效果。

3.3 實驗程式碼

def biKmeans(dataSet, k,distMeas=distEclud):

    m= shape(dataSet)[0]

   clusterAssment = mat(zeros((m,2)))

    centroid0= mean(dataSet, axis=0).tolist()[0]

   centList =[centroid0] #create a list with one centroid

   for j in range(m):#calc initial Error

       clusterAssment[j,1] = distMeas(mat(centroid0), dataSet[j,:])**2

   while (len(centList) < k):

       lowestSSE = inf

       for i in range(len(centList)):

           ptsInCurrCluster = dataSet[nonzero(clusterAssment[:,0].A==i)[0],:]#getthe data points currently in cluster i

           centroidMat, splitClustAss = kMeans(ptsInCurrCluster, 2, distMeas)

           sseSplit = sum(splitClustAss[:,1])#compare the SSE to the currrentminimum

           sseNotSplit =sum(clusterAssment[nonzero(clusterAssment[:,0].A!=i)[0],1])

           print("sseSplit, and notSplit: ",sseSplit,sseNotSplit)

           if (sseSplit + sseNotSplit)< lowestSSE:

                bestCentToSplit = i

                bestNewCents = centroidMat

                bestClustAss =splitClustAss.copy()

                lowestSSE = sseSplit +sseNotSplit

       bestClustAss[nonzero(bestClustAss[:,0].A == 1)[0],0] = len(centList)#change 1 to 3,4, or whatever

       bestClustAss[nonzero(bestClustAss[:,0].A == 0)[0],0] = bestCentToSplit

       print('the bestCentToSplit is: ',bestCentToSplit)

       print('the len of bestClustAss is: ', len(bestClustAss))

       centList[bestCentToSplit] = bestNewCents[0,:].tolist()[0]#replace acentroid with two best centroids

       centList.append(bestNewCents[1,:].tolist()[0])

       clusterAssment[nonzero(clusterAssment[:,0].A == bestCentToSplit)[0],:]=bestClustAss#reassign new clusters, and SSE

   return mat(centList), clusterAssment

四、程式例項(對地圖上的點聚類)

4.1 採用演算法:二分K均值

    資料集:地圖


4.2 使用Yahoo PlaceFinder API獲得地圖上的每個點的經緯度


4.3 實驗結果


五、總結與體會

優點:容易實現

缺點:可能收斂到區域性最小值,在大規模資料集上收斂較慢

六、參考文獻

【1】《機器學習實戰》Peter Harrington

【2】《資料探勘-概念與技術》JiaWei Han、Micheline Kamber、Jian Pei

非常感謝閱讀!如有不足之處,請留下您的評價和問題