R數據挖掘 第一篇:聚類分析(劃分)

聚類是把一個數據集劃分紅多個子集的過程,每個子集稱做一個簇(Cluster),聚類使得簇內的對象具備很高的類似性,但與其餘簇中的對象很不類似,由聚類分析產生的簇的集合稱做一個聚類。在相同的數據集上,不一樣的聚類算法可能產生不一樣的聚類。html

聚類分析用於洞察數據的分佈,觀察每一個簇的特徵,進一步分析特定簇的特徵。因爲簇是數據對象的子集合,簇內的對象彼此類似,而與其餘簇的對象不類似,所以,簇能夠看做數據集的「隱性」分類,聚類分析可能會發現數據集的未知分組。算法

聚類經過觀察學習,不須要提供每一個訓練元素的隸屬關係,屬於無監督式學習(unspervised learning),無監督學習是指在沒有標註的數據中尋找隱含的結構信息。數據的內部構造描繪了要分組的對象,而且決定了如何最佳地把數據對象分組。主要的聚類算法能夠分爲如下四類:ide

  • 劃分聚類(Partitioning Clustering)
  • 層次聚類(Hierarchical clustering)
  • 基於密度的方法
  • 基於網格的方法

本文簡單介紹最簡單的劃分聚類算法,劃分聚類是指:給定一個n個對象的集合,劃分方法構建數據的k個分組,其中,每一個分區表示一個簇,而且 k<= n,也就是說,把數據劃分爲k個組,使得每一個組至少包含一個對象,基本的劃分方法採起互斥的簇劃分,這使得每一個對象都僅屬於一個簇。爲了達到全局最優,基於劃分的聚類須要窮舉全部可能的劃分,計算量極大,實際上,經常使用的劃分方法都採用了啓發式方法,例如k-均值(k-means)、k-中心點(k-medoids),漸進地提升聚類質量,逼近局部最優解,啓發式聚類方法比較適合發現中小規模的球狀簇。函數

一,k-均值

k-均值(kmeans)是一種基於形心的計數,每個數據元素的類型是數值型,k-均值算法把簇的形心定義爲簇內點的均值,k-均值算法的過程:性能

輸入:  k(簇的數目),D(包含n個數據的數據集)學習

輸出:  k個簇的集合idea

算法:spa

  1. 從D中任意選擇k個對象做爲初始簇中心;
  2. repeat
  3.   根據cu中對象的均值,把每一個對象分配到最類似的簇;
  4.   更新簇的均值,即從新計算每一個簇中對象的均值;
  5. until 簇均值再也不發生變化

不能保證k-均值方法收斂於全局最優解,但它經常終止於局部最優解,該算法的結果可能依賴於初始簇中心的隨機選擇。.net

k-均值方法不適用於非凸形的簇,或者大小差異很大的簇,此外,它對離羣點敏感,由於少許的離羣點可以對均值產生極大的影響,影響其餘簇的分配。code

R語言中,stats包中的kmeans()函數用於實現k-均值聚類分析:

kmeans(x, centers, iter.max = 10, nstart = 1,
       algorithm = c("Hartigan-Wong", "Lloyd", "Forgy","MacQueen"), trace=FALSE)

參數註釋:

  • x:數值型的向量或矩陣
  • centers:簇的數量
  • iter.max:重複的最大數量,默認值是10
  • nstart:隨機數據集的數量,默認值是1
  • algorithm:算法的選擇,默認值是Hartigan-Wong

函數返回的值:

  • cluster :整數向量,整數值是從1到k,表示簇的編號
  • centers:每一個簇的中心,按照簇的編號排列
  • size:每一個簇包含的點的數量

二,k-中心點

k-中心點不使用簇內對象的均值做爲參照點,而是挑選實際的數據對象p來表明簇,其他的每一個對象被分配到與其最爲類似的對象表明p所在的簇中。一般狀況下,使用圍繞中心點劃分(Partitioning Around Medoids,PAM)算法實現k-中心點聚類。

PAM算法的實現過程:

輸入:  k(簇的數目),D(包含n個數據的數據集)

輸出:  k個簇的集合

算法:

  • 從D中隨機選擇k個對象做爲初始的表明對象或種子;
  • repeat
  •   把每一個剩餘的對象分配到最近的表明對象p所在的簇;
  •   隨機地選擇一個非表明對象R
  •   計算用R代替表明對象p的總代價S;
  •   if S<0 then 使用R代替p,造成新的k個表明對象的集合;
  • until  表明對象再也不變化

當存在離羣點時,k-中心點方法比k-均值法更魯棒(所謂「魯棒性」,是指控制系統在必定(結構,大小)的參數攝動下,維持某些性能的特性),這是由於中心點不像均值法那樣容易受到離羣點或其餘極端值的影響。可是,當n和k的值較大時,k-中心點計算的開銷變得至關大,遠高於k-均值法。

R語言中,cluster包中的pam()函數用於實現k-中心點聚類分析:

pam(x, k, diss = inherits(x, "dist"),metric = c("euclidean", "manhattan"), medoids = NULL, stand = FALSE, ... )

參數註釋:

  • diss:邏輯值,默認值是TRUE,當diss爲TRUE時,x參數被認爲是相異矩陣(dissimilarity matrix);當diss爲FALSE時,x參數被認爲是包含變量的觀測矩陣
  • metric:字符類型,用於指定用於在兩個觀測之間計算差別的度量(mertic),有效值是"euclidean" 和"manhattan",分別用於計算歐幾里德距離和曼哈頓距離,若是diss參數爲TRUE,那麼該參數會被忽略。
  • medoids:默認值是NULL,用於指定聚類的初始的中心點。
  • stand:邏輯值,默認值是FALSE。若是設置爲TRUE,那麼在對x計算相異度量以前,按照列對x進行標準化(無量綱化處理),也就是說,對每列的數據進行標準化。標準化操做算法是:經過減去變量的平均值併除以變量的平均絕對誤差,對每一個變量(列)進行標準化測量。 若是x已是相異矩陣,則該參數將被忽略。

函數返回的對象:

  • medoids:每一個簇的中心點
  • clustering:向量,用於表示每一個觀測所屬於的簇
  • silinfo:輪廓數據,包括每一個觀測的輪廓係數,每一個簇的平均輪廓係數,整個數據集的平均輪廓係數。

三,聚類評估

當咱們再數據集上試用一種聚類方法時,如何評估聚類的結果的好壞?通常來講,聚類評估主要包括如下任務:

  • 估計聚類趨勢:僅當數據中存在非隨機數據時,聚類分析纔是有意義的,所以,評估數據集是否存在隨機數據。
  • 肯定數據集中的簇數:在使用聚類算法以前,須要估計簇數
  • 測定聚類質量:在數據集上使用聚類方法以後,須要評估簇的質量。

1,估計聚類趨勢

聚類要求數據是非均勻分佈的,霍普金斯統計量是一種空間統計量,用於檢驗空間分佈的變量的空間隨機性。

comato包中有一個Hopkins.index()函數,用於計算霍普金斯指數,若是數據分佈是均勻的,則該值接近於0.5,若是數據分佈是高度傾斜的,則該值接近於1。

library(comato)
Hopkins.index(data)

要使用Hopkins.index()評估數據的空間隨機性,須要對數據進行無量綱化處理。

2,肯定最佳的簇數

一般狀況下,使用肘方法(elbow)以肯定聚類的最佳的簇數,肘方法之因此是有效的,是基於如下觀察:增長簇數有助於下降每一個簇的簇內方差之和,給定k>0,計算簇內方差和var(k),繪製var關於k的曲線,曲線的第一個(或最顯著的)拐點暗示正確的簇數。

sjPlot包中sjc.elbow()函數實現了肘方法,能夠用於肯定k-均值聚類的簇的數目:

library(sjPlot)
sjc.elbow(data, steps = 15, show.diff = FALSE)

參數註釋:

  • steps:最大的肘值的數量
  • show.diff:默認值是FALSE,額外繪製一個圖,鏈接每一個肘值,用於顯示各個肘值之間的差別,改圖有助於識別「肘部」,暗示「正確的」簇數。

sjc.elbow()函數用於繪製k-均值聚類分析的肘值,該函數在指定的數據框計算k-均值聚類分析,產生兩個圖形:一個圖形具備不一樣的肘值,另外一個圖形是鏈接y軸上的每一個「步」,即在相鄰的肘值之間繪製連線,第二個圖中曲線的拐點可能暗示「正確的」簇數。

繪製k均值聚類分析的肘部值。 該函數計算所提供的數據幀上的k均值聚類分析,併產生兩個圖:一個具備不一樣的肘值,另外一個圖繪製在y軸上的每一個「步」(即在肘值之間)之間的差別。 第二個圖的增長可能代表肘部標準。

library(effects)
library(sjPlot)
library(ggplot2)

sjc.elbow(mtcars,show.diff = FALSE)

從肘值圖中,能夠看到曲線的拐點是3,還可使用NbClust包種的NbClust()函數,該函數提供了26個不一樣的指標來幫助肯定簇的最終數目。

library(NbClust)

nc <- NbClust(df,min.nc = 2,max.nc = 15,method = "kmeans")
barplot(table(nc$Best.nc[1,]),xlab="Number of Clusters",ylab="Number of Criteria",main="number of Clusters Chosen by 26 Criteria")

從條形圖種,能夠看到支持簇數爲3的指標(Criteria)的數量是最多的,所以,基本上能夠肯定,k-均值聚類的簇數目是3。

3,測定聚類質量

如何比較不一樣聚類算法產生的聚類?通常而言,根據是否有基準可用,把測定聚類質量的方法分爲兩類:外在方法和內在方法。

基準是一種理想的聚類,一般由專家構建。若是有可用的基準,那麼能夠把聚類和基準進行比較,這種方法叫作外在方法。若是沒有基準可用,那麼經過考慮簇的分離狀況來評估簇的好壞,這種方法叫作內在方法。

(1)外在方法

當有基準可用時,使用BCubed 精度(precision)和召回率(recall)來評估聚類的質量。

BCubed根據基準,對給定數據集上聚類中每一個對象評估精度(precision)和召回率(recall)。一個對象的精度是指同一簇中有多少個其餘對象與該對象同屬於一個類別;一個對象的召回率反映有多少同一類別的對象被分配到相同的簇中。

(2)內在方法

當沒有數據集的基準可用時,必須使用內在方法來評估聚類的質量。通常而言,內在方法經過考察簇的分離狀況和簇的緊湊狀況來評估聚類,一般的內在方法都使用數據集的對象之間的類似性度量來實現。

輪廓係數(silhouette coefficient)就是這種類似性度量,輪廓係數的值在-1和1之間,該值越接近於1,簇越緊湊,聚類越好。當輪廓係數接近1時,簇內緊湊,並遠離其餘簇。

若是輪廓係數sil 接近1,則說明樣本聚類合理;若是輪廓係數sil 接近-1,則說明樣本i更應該分類到另外的簇;若是輪廓係數sil 近似爲0,則說明樣本i在兩個簇的邊界上。全部樣本的輪廓係數 sil的均值稱爲聚類結果的輪廓係數,是該聚類是否合理、有效的度量。

包fpc中實現了計算聚類後的一些評價指標,其中就包括了輪廓係數:avg.silwidth(平均的輪廓寬度)

library(fpc)
result <- kmeans(data,k)
stats <- cluster.stats(dist(data)^2, result$cluster)
sli <- stats$avg.silwidth

包cluster中也包括計算輪廓係數的函數silhouette():

library (cluster)
library (vegan)

#pam
dis <- vegdist(data)
res <- pam(dis,3) 
sil <- silhouette (res$clustering,dis)

#kmeans
dis <- dist(data)^2
res <- kmeans(data,3)
sil <- silhouette (res$cluster, dis)

四,k-均值聚類分析實踐

有效的聚類分析是一個多步驟的過程,其中每一次決策均可能影響聚類結果的質量和有效性,咱們使用k-均值聚類來處理葡萄酒中13種化學成分的數據集wine,這個數據集能夠經過rattle包得到,

install.packages("rattle")
data(wine,package="rattle")
head(wine)

  Type Alcohol Malic  Ash Alcalinity Magnesium Phenols Flavanoids Nonflavanoids Proanthocyanins Color  Hue Dilution Proline
1    1   14.23  1.71 2.43       15.6       127    2.80       3.06          0.28            2.29  5.64 1.04     3.92    1065
2    1   13.20  1.78 2.14       11.2       100    2.65       2.76          0.26            1.28  4.38 1.05     3.40    1050
3    1   13.16  2.36 2.67       18.6       101    2.80       3.24          0.30            2.81  5.68 1.03     3.17    1185
4    1   14.37  1.95 2.50       16.8       113    3.85       3.49          0.24            2.18  7.80 0.86     3.45    1480
5    1   13.24  2.59 2.87       21.0       118    2.80       2.69          0.39            1.82  4.32 1.04     2.93     735
6    1   14.20  1.76 2.45       15.2       112    3.27       3.39          0.34            1.97  6.75 1.05     2.85    1450

1,選擇合適的變量

第一個變量Type是類型,能夠忽略,其餘13個變量是葡萄酒的13總化學成分,選擇這13個變量進行聚類分析。因爲變量值變化很大,因此須要在聚類以前對其進行標準化處理。

2,標準化數據

使用scale()函數對數據進行無量綱化處理,

df <- scale(wine[,-1])

3,評估聚類的趨勢

變量df的變量值是無量綱的,能夠直接使用函數Hopkins.index()計算數據的空間分佈的隨機性,得出的結果越接近於1,說明數據的空間分佈高度傾斜,空間隨機性越高。

install.packages("comato")
library(comato) Hopkins.index(df) [
1] 0.7412846

4,肯定聚類的簇數

使用sjPlot包中的sjc.elbow()函數計算肘值,曲線的拐點出現3左右,這說明,使用k-均值法進行聚類分析時,能夠設置的簇數大概是3。

install.packages("effects")
install.packages("sjplot")

library(effects)
library(sjPlot)
library(ggplot2)

sjc.elbow(df,show.diff = FALSE)

 

從肘值圖中,能夠看到曲線的拐點是3,還可使用NbClust包種的NbClust()函數,該函數提供了26個不一樣的指標來幫助肯定簇的最終數目。

install.packages("NbClust")
library(NbClust)

nc <- NbClust(df,min.nc = 2,max.nc = 15,method = "kmeans")
barplot(table(nc$Best.nc[1,]),xlab="Number of Clusters",ylab="Number of Criteria",main="number of Clusters Chosen by 26 Criteria")

從條形圖種,能夠看到支持簇數爲3的指標(Criteria)的數量是最多的,所以,基本上能夠肯定,k-均值聚類的簇數目是3。

5,測定聚類的質量

使用輪廓係數測定聚類的質量,輪廓係數的值在-1和1之間,該值越接近於1,簇越緊湊,聚類越好。當輪廓係數接近1時,簇內緊湊,並遠離其餘簇。

install.packages("fpc")

library(fpc)
for(k in 2:9){ result <- kmeans(df,k) stats <- cluster.stats(dist(df)^2, result$cluster) sli <- stats$avg.silwidth print(paste0(k,'-',sli)) }

當簇數目爲3時,聚類的輪廓係數0.45是最好的。

[1] "2-0.425791262898175"
[1] "3-0.450837233419168"
[1] "4-0.35109709657011"
[1] "5-0.378169006474844"
[1] "6-0.292436629924875"
[1] "7-0.317163857046711"
[1] "8-0.229405778112672"
[1] "9-0.291438101137107"

 

參考文檔:

多種常見聚類模型以及分羣質量評估(聚類注意事項、使用技巧)

肯定最佳聚類數目的10種方法

相關文章
相關標籤/搜索