聚類分析方法學習
本文章僅供參考似踱,如果有什么不對墓臭,請多多指教!
分類
??1.層次聚類分析(150個觀測值或者更衅鸨恪)2.劃分聚類分析(大樣本分析):K-Mean聚類分析和基于中心點的劃分
注意
1. 層次聚類分析
??1. 選擇合適的變量榆综;
??2.選擇變量前先去掉部分不可取變量,縮放數據鼻疮,可用標準化,最大最小標準化等方法耿芹;
??3.尋找異常點挪哄,通過outliers包中的函數進行篩選和刪除異常單變量離群,或者用mvoutliers包圍繞著中心點進行劃分砸彬;
??4.計算距離斯入,一般是歐幾里得距離,其中包括曼哈頓距離刻两、最大距離等,可以調用dist()函數進行計算滋迈;
??5.選擇聚類算法户誓,樣本少的采用層次聚類分析,樣本多的采用劃分聚類分析赔退;
??6.獲得一種或者多種的聚類分析方法;
??7.確定類的數目硕旗,一般調用NbClust()函數去確定;
??8.獲得最終的聚類解決方案创译;
??9.結果可視化墙基,一般觀察樹狀圖;
??10.解讀類立砸;
??11.驗證結果初茶,利用fpc、clv和clValid包包含評估聚類解的穩(wěn)定性的函數螺戳。
2. 劃分聚類分析:K-均值聚類和基于中心點的劃分(PAM)
2.1 K-均值聚類分析
??1.選擇k個中心點折汞;
??2.把每個數據點分配到離它最近的中心點著摔;
??3.重新計算每類中的點到該類中心點距離的平均值惋增;
??4.分配每個數據到它最近的中心點堕伪;
??5.重復3和4的步驟直到所有觀測值不再被分配或是達到最大的迭代次數(默認:10次)栗菜;
其中停止的時候使得觀測值到其指定的聚類中心的平方總和最小疙筹,即
最小。
??6.注意:平方總和最小的條件限制了所有變量必須是連續(xù)的而咆,而且容易被異常值所影響暴备;同時對初始中心值的選擇十分敏感,可用nstart()函數嘗試多種初始配置并輸出最好的那個。其中k的取值跟層次分析一樣重要望迎,可以用NbClust()函數進行參考凌外,也可以借助類中總的平方值對聚類數量的曲線,也就是代碼中的wssplot()函數就可以繪畫出SSE函數摄欲。
2.2 基于中心點的劃分
??K-均值聚類分析是利用歐幾里得距離進行聚類分析疮薇,而Pam聚類分析是采用任意距離惦辛,可以容納混合數據類型,不僅限于連續(xù)變量胖齐。PAM算法如下:
??1.隨機選擇K個觀測值(每個都稱為中心點)呀伙;
??2.計算觀測值到各個中心的距離/相異性;
??3.把每個觀測值分配到最近的中心點剿另;
??4.計算每個中心點到每個觀測值的距離的總和(總成本)雨女;
??5.選擇一個該類中不是中心的點,并和中心點互換馏臭;
??6.重新把每個點分配到距離它最近的中心點讼稚;
??7.再次計算總成本;
??8.如果總成本比步驟(4)計算的總成本少帮寻,把新的點作為中心點赠摇;
??9.重復步驟(5)-(8)直到中心點不再改變.
R語言代碼
1. 計算距離
data(nutrient,package="flexclust")
head(nutrient,4)
d<-dist(nutrient)
as.matrix(d)[1:4,1:4]#強制轉化為矩陣
??注:可用cluster包中的daisy()函數獲得包含任意二元、名義抒蚜、有序屬性組合的相異矩陣。
2. 層次聚類分析
data(nutrient,package="flexclust")
row.names(nutrient)<-tolower(row.names(nutrient))#tolower()將字體全部改成小寫操漠,toupper()將字體全部改成大寫
nutrient.scaled<-scale(nutrient)#對數據進行標準化
d<-dist(nutrient.scaled)
fit.average<-hclust(d,method="average")#對距離進行層次聚類分析
dev.new()
plot(fit.average,hang=-1,cex=.8,main="Average Linkage Clustering")
??注:層次聚類分析就是將距離最短的兩類合并成一類浊伙,從而把所有類合并成單個類為止长捧,其中距離定義有:1.單聯(lián)動(細長、雪茄型數據)哑子;2.全聯(lián)動(大致相等的直徑緊湊型)肌割;3.平均聯(lián)動(偏向于方差較小的聚類)把敞;4.質心(變量均值向量之間的距離);5.Ward法(所有變量的方差分析的平方和)盛霎。層次聚類方法用hclust()函數耽装,其中method=single,complete,average,controid,ward掉奄。
-
選擇聚類的個數
library(NbClust)
dev.new()
devAskNewPage(ask=TRUE)
nc<-NbClust(nutrient.scaled,distance="euclidean",min.nc=2,max.nc=15,method="average")#對變量進行分類
table(nc$Best.n[1,])
barplot(table(nc$Best.n[1,]),xlab="Name of Clusters",ylab="Name of Criteria",main="Number of Cluster Chosen by 26 Criteria")
??注:根據最后一個直方圖挥萌,值最大的就用K的數目枉侧,觀察上圖榨馁,可以發(fā)現(xiàn)K=2、3屑柔、5掸宛、15是最好的選擇,最后需要測試一下哪個K值最好措译。
-
最后的方案
clusters<-cutree(fit.average,k=5)#對進行聚類分析的變量進行繪畫樹狀圖领虹,并分為5類
table(clusters)
aggregate(nutrient,by=list(cluster=clusters),median)#對組合后的數據進行求中位數
aggregate(as.data.frame(nutrient.scaled),by=list(cluster=clusters),median)
dev.new()
plot(fit.average,hang=-1,cex=.8,main="Average Linkage Clustering\n5 Cluster Solution")#對進行聚類分析的變量進行重新繪制樹狀圖
rect.hclust(fit.average,k=5)#對進行聚類分析的變量疊加 5類的解決方案
??注:生物科學中經常使用層次聚類分析方法塌衰,不過這種算法是貪婪的最疆,一旦一個觀測值被分配給一個類是晨,它就不能在后面進行重新分配罩缴,如果在大樣本中箫章,用劃分聚類分析比較合適。
3. 劃分聚類分析
3.1 K-均值聚類分析
-
生成計算SSE函數
wssplot <- function(data, nc=15, seed=1234){
wss <- (nrow(data)-1)*sum(apply(data,2,var))#此處使用apply函數
for (i in 2:nc){
set.seed(seed)#保證結果是可復制的
wss[i] <-sum(kmeans(data,centers=i)$withiness)#withiness是組內平方和
}
plot(1:nc,wss,type="b",xlab="Number of Clusters", ylab="Within groups sum of squares")}
-
讀取葡萄酒數據
library(rattle)
data(wine,package="rattle")
head(wine)
-
確定K的個數
library(NbClust)
df <- scale(wine[-1])
wssplot(df)
set.seed(1234)
dev.new()
devAskNewPage(ask=TRUE)
nc <- NbClust(df,min.nc=2,max.nc=15,method="kmeans")
table(nc$Best.n[1,])
barplot(nc$Best.n[1,],xlab="Number of Clusters",ylab="Number of Criteria",main="Number of Clusters Chosen by 26 Criteria")
-
從上述的圖表,可以看到聚類數目K=3昼伴,對df進行K均值聚類
set.seed(1234)
fit.km <- kmeans(df,3,nstart=25)
fit.km$size
fit.km$centers
aggregate(wine[-1],by=list(cluster=fit.km$cluster),mean)#總結該變量的平均值
ct.km <- table(wine$Type,fit.km$cluster)
ct.km
library(flexclust)
randIndex(ct.km)#蘭德指數:為兩種劃分提供了一種衡量兩種分區(qū)之間的協(xié)定:K-均值聚類分析和PAM聚類分析
3.2 PAM聚類分析
library(cluster)
set.seed(1234)
fit.pam<-pam(wine[-1],k=3,stand=TRUE)#stand表示該變量是否標準化
fit.pam$medoids#輸出中心點
clusplot(fit.pam,main="Bivariate Cluster Plot")
ct.pam <- table(wine$Type,fit.pam$clustering)#此處的cluster和clustering一樣
ct.pam
randIndex(ct.pam)#由于pam中的蘭德指數比K-均值的蘭德指數低圃郊,所以建議選擇K-均值聚類分析
-
避免不存在的類
library(fMultivar)
library(NbClust)
library(cluster)
library(ggplot2)
set.seed(1234)
df <- rnorm2d(1000,rho=.5)#rnorm()生成標準正態(tài)分布的隨機數持舆,而rnorm2d()生成相關系數為0.5的正態(tài)分布
df <- as.data.frame(df)
plot(df,main="Bivariate Normal Distribution with rho=0.5")
wssplot(df)
nc <- NbClust(df,min.nc=2,max.nc=15,method="kmeans")
dev.new()
barplot(table(nc$Best.n[1,]),xlab="Number of Clusters",ylab="Number of Criteria",main="Number of Chosen by 26 Criterias")#建議k=3
fit <- pam(df,k=2)
df$clustering <- factor(fit$clustering)
ggplot(data=df,aes(x=V1,y=V2,color=clustering,shape=clustering))+geom_point()+ggtitle("Clustering of Bivariate Normal Data")
plot(nc$All.index[,4],type="o",ylab="CCC",xlab="Number of clusters",col="blue")
??注:最后一個plot中的CCC是調用了NbCluster包中的立方聚類規(guī)則居兆,揭示不存在的類竹伸,通過分析勋篓,該圖中的CCC值都是負值并且對于兩類或是更多的類遞減時生巡,就是典型的單峰分布,就是偏左正態(tài)分布或者偏右正態(tài)分布甸陌。