1. 程式人生 > >K-means和K-medoids

K-means和K-medoids

聚類問題是將一組物件分成若干個群體,每個群體構成一個簇,使得簇內的物件儘可能具有最大的相似性,不同簇之間的物件儘可能有最大的相異性,聚類過程是一個尋找最優劃分的過程,即根據聚類質量的評價準則或方法不斷對劃分進行優化,最終得到最優解。由於聚類是無指導的學習過程事先對資料的結構是未知的,因此,最終的聚類結果都需要進行有效性驗證和質量評價。
一般來說  評價聚類和選擇最優聚類模式的原則有兩個:緊密度,即簇中的成員必須儘可能地相互靠近。分離度,簇與簇之間的距離儘可能地遠。大多數評價聚類質量的方法都是基於這兩個原則。
K-means演算法通過計算一類記錄的均值來代表該類,但是受異常值或極端值的影響比較大。
K-means比較相似另一種演算法K-medoids,它通過中心點的迭代輪換及最小化類內差異完成資料物件聚類。首先隨機初始中心,然後將其餘物件分配給最近的簇;在反覆用非中心點來替代中心點後重復分配過程,以提高聚類質量至聚類質量不再變化。而在K-means中,我們將中心點取為當前cluster中所有資料點的平均值。如下圖所示,在K-medoids中,需要計算每一個未被選中的資料點h和選中的資料點i的交換代價TCih,如果TCih<0,就用h替換。其中TCih= Cjih,Cjih = d(j, h) - d(j, i)。
K-means  K-medoids 之間的差異就類似於一個數據樣本的均值和中位數之間的差異:前者的取值範圍可以是連續空間中的任意值,而後者只能在給樣本給定的那些點裡面選。
K-means 對資料的要求太高了,它使用歐氏距離描述資料點之間的差異,從而可以直接通過求均值來計算中心點,但是這要求資料點處在一個歐氏空間之中。然而並不是所有的資料都能滿足這樣的要求,對於數值型別的特徵,比如畫素點,可以很自然地用這樣的方式來處理,但是類別型別的特徵就不行,比如對電影進行聚類,兩部電影相減的平方就沒有意義。另外,K-means必須有如下三個條件保證:
1、所有的屬性或者變數的方差分佈是球形的; 2、所有的變數都有相同的方差; 3、所有k個聚類的先驗概率是相同的,即每個聚類中的觀測點個數大致相同; 下面給出K-means的R程式碼
> iris2  <-  iris
> iris2$Species  <-  NULL
> kmeans.result  <-  kmeans(iris2,  3)
> kmeans.result
K-means clustering with 3 clusters of sizes 62, 50, 38

Cluster means:
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.901613    2.748387     4.393548    1.433871
2     5.006000    3.428000     1.462000    0.246000
3     6.850000    3.073684     5.742105    2.071053

Clustering vector:
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [37] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [73] 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 3 3 3 3 1 3
[109] 3 3 3 3 3 1 1 3 3 3 3 1 3 1 3 1 3 3 1 1 3 3 3 3 3 1 3 3 3 3 1 3 3 3 1 3
[145] 3 3 1 3 3 1

Within cluster sum of squares by cluster:
[1] 39.82097 15.15100 23.87947
 (between_SS / total_SS =  88.4 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"    
[5] "tot.withinss" "betweenss"    "size"         "iter"        
[9] "ifault"      
>  table(iris$Species,  kmeans.result$cluster)
            
              1  2  3
  setosa      0 50  0
  versicolor 48  0  2
  virginica  14  0 36
> plot(iris2[c("Sepal.Length",  "Sepal.Width")],  col  =  kmeans.result$cluster)
> points(kmeans.result$centers[,c("Sepal.Length",  "Sepal.Width")],  col  =  1:3,
+        pch = 8,  cex=2)

下面給出K-medoids的R程式碼: PAM (Partitioning Around Medoids)是K-medoids常用的演算法。
> library(fpc)
> pamk.result  <-  pamk(iris2)
> #  number  of  clusters
> pamk.result$nc
[1] 2
> #  check  clustering  against  actual  species
> table(pamk.result$pamobject$clustering,  iris$Species)
   
    setosa versicolor virginica
  1     50          1         0
  2      0         49        50
> layout(matrix(c(1,2),1,2))  #  2  graphs  per  page
> plot(pamk.result$pamobject)
參考資料: