R語言擁有大量和聚類分析相關的函式,在這裡我主要會和大家介紹K-means聚類、層次聚類和基於模型的聚類。
1. 資料預處理
在進行聚類分析之前,你需要進行資料預處理,這裡主要包括缺失值的處理和資料的標準化。我們仍然以鳶尾花資料集(iris)為例進行詳細講解:
# 資料預處理
mydata <- iris[,1:4] # 只提取前4列資料,不包括類別這個變數
mydata <- na。omit(mydata) # 刪除缺失值
mydata <- scale(mydata) # 資料標準化
2. K-means聚類
在聚類分析中,K-means聚類演算法是最常用的,它需要分析者先確定要將這組資料分成多少類,也即聚類的個數,這個通常可以用因子分析的方法來確定。比如我們可以用“nFactors”包的函式來確定最佳的因子個數,將因子數作為聚類數,不過關於聚類個數的確定還要考慮資料的實際情況與自身需求,這樣分析才會更具有現實意義。 另外,我們也可以透過繪製碎石圖來確定聚類個數,這和主成分的思想相似。
# 利用碎石圖確定聚類個數
wss <- (nrow(mydata)-1)*sum(apply(mydata,2,var)) # 計算離均差平方和
for (i in 2:15) wss[i] <- sum(kmeans(mydata,
centers=i)$withinss) #計算不同聚類個數的組內平方和
plot(1:15, wss, type=“b”, xlab=“Number of Clusters”,
ylab=“Within groups sum of squares”) # 繪圖
一般我們需要控制組內平方和的值要小,同時聚類的個數也不能太多,所以從圖中可以看出聚類個數定在2~3比較好。
# K-Means聚類分析
fit1 <- kmeans(mydata, 3) # 設定聚類個數為3
# 獲取聚類均值
aggregate(mydata,by=list(fit1$cluster),FUN=mean) # aggregate()是一個分類彙總函式
從上面的結果中我們可以看出不同類別的各變數均值,從而對各類的特徵有總體的瞭解,比如第2類是花瓣和花萼都普遍偏大的一類。
# 返回聚類的結果
res <- data。frame(mydata, fit1$cluster)
大家可以拿返回的聚類結果和真實分類對比一下,看看此次聚類效果如何。
3. 層次聚類
R語言提供了豐富的層次聚類函式,這裡我給大家簡單介紹一下用Ward方法進行的層次聚類分析。
# Ward層次聚類
d <- dist(mydata, method = “euclidean”) # 計算各個樣本點之間的歐氏距離
fit2 <- hclust(d, method=“ward。D”) #進行Ward層次聚類
plot(fit2) # 繪製樹狀圖展示聚類結果
groups <- cutree(fit2, k=3) # 設定聚類個數為3
# 給聚成的3個類別加上紅色邊框
rect。hclust(fit2, k=3, border=“red”)
4. 基於模型的聚類
基於模型的聚類方法利用極大似然估計法和貝葉斯準則在大量假定的模型中去選擇最佳的聚類模型並確定最佳聚類個數。我們可以使用R包“mclust”的Mclust()函式來實現這種模型聚類分析,同時你可以透過help(mclustModelNames)去檢視各類模型的詳細資訊。
# 基於模型的聚類分析
library(mclust)
fit3 <- Mclust(mydata)
plot(fit3) # 繪圖
summary(fit3) # 輸出結果
從上面的結果來看,將總體聚成兩類比較合適!
4. 聚類結果形象化展示
# 聚類結果展示
# 將原資料聚成兩類
fit4 <- kmeans(mydata, 2)
# 用前兩個主成分繪製聚類圖
library(cluster)
clusplot(mydata, fit4$cluster, color=TRUE, shade=TRUE,
labels=2, lines=0)
從圖中看,樣本被清晰分成兩類,結果看起來挺不錯的。
經過上述一系列的聚類分析,我們發現:如果僅僅使用花瓣和花萼的資料,鳶尾花資料集聚成兩類最好,其中第一類是“setosa”,第二類則是“versicolor”和“virginica”。雖然該資料集自然分類是3類,但我們發現強行分成三類的效果並不好,這主要是因為僅僅利用花瓣和花萼的資料還無法將“versicolor“和”virginica“這兩類進行很好的區分。
其實,在之前的判別分析中,我們已經發現”setosa”這一類的判別結果和其餘兩類均沒有重疊,而“versicolor“和”virginica“這兩個資料的線性判別的重疊部分較多,不好區分。
最後,如果真正想提高聚類結果和真實分類的接近度,我們通常需要增加有效的變數,這個才是關鍵!