我們之前經常提起的K-means算法雖然比較經典,但其有不少的局限,為了改變K-means對異常值的敏感情況,我們介紹了K-medoids算法,而為了解決K-means只能處理數值型數據的情況,本篇便對K-means的變種算法——K-modes進行簡介及Python、R的實現:
K-modes是數據挖掘中針對分類屬性型數據進行聚類采用的方法,其算法思想比較簡單,時間復雜度也比K-means、K-medoids低,大致思想如下:
假設有N個樣本,共有M個屬性,均為離散的,對於聚類數目標K:
step1:隨機確定k個聚類中心C1,C2...Ck,Ci是長度為M的向量,Ci=[C1i,C2i,...,CMi]
step2:對於樣本xj(j=1,2,...,N),分別比較其與k個中心之間的距離(這里的距離為不同屬性值的個數,假如x1=[1,2,1,3],C1=[1,2,3,4]x1=[1,2,1,3],C1=[1,2,3,4],那么x1與C1之間的距離為2)
step3:將xj划分到距離最小的簇,在全部的樣本都被划分完畢之后,重新確定簇中心,向量Ci中的每一個分量都更新為簇i中的眾數
step4:重復步驟二和三,直到總距離(各個簇中樣本與各自簇中心距離之和)不再降低,返回最后的聚類結果
下面對一個簡單的小例子在Python與R中的K-modes聚類過程為例進行說明:
Python
我們使用的是第三方包kmodes中的方法,具體過程如下:
import numpy as np from kmodes import kmodes '''生成互相無交集的離散屬性樣本集''' data1 = np.random.randint(1,6,(10000,10)) data2 = np.random.randint(6,12,(10000,10)) data = np.concatenate((data1,data2)) '''進行K-modes聚類''' km = kmodes.KModes(n_clusters=2) clusters = km.fit_predict(data) '''計算正確歸類率''' score = np.sum(clusters[:int(len(clusters)/2)])+(len(clusters)/2-np.sum(clusters[int(len(clusters)/2):])) score = score/len(clusters) if score >= 0.5: print('正確率:'+ str(score)) else: print('正確率:'+ str(1-score))
R
在R中進行K-modes聚類的包為klaR,用其中的kmodes(data,modes=k)進行聚類,其中modes為指定的類數目k,具體示例如下:
> library(klaR) > > data1 <- matrix(sample(1:3,size=1000,replace = T),nrow=100) > data2 <- matrix(sample(4:6,size=1000,replace = T),nrow=100) > data <- rbind(data1,data2) > > km <- kmodes(data, modes=2) > s <- km$cluster > if(mean(s[1:100] < 1.5)){ + score <- sum(s[1:100])+sum(s[101:200]-1) + score <- score/200 + cat('正確率:',score) + }else{ + score <- sum(s[1:100]-1)+sum(s[101:200]) + score <- score/200 + cat('正確率:',round(score,3)) + } 正確率: 0.995
以上便是關於K-modes聚類的簡要介紹,如有錯誤望指出。