第9章 聚類

不同于分類和回歸,聚類不需要事先的任何參考分類信息,可以簡單地通過判斷數(shù)據(jù)特征的相似性來完成對數(shù)據(jù)的歸類。

  • 層次聚類
    不需要事先指定族的個數(shù),以系統(tǒng)樹的形式展現(xiàn)。
  • k均值聚類
    扁平聚類,不會生成聚類層次,需要事先確定族的個數(shù),性能優(yōu)于層次聚類。
  • 基于模型的聚類
    以上兩種是啟發(fā)式聚類,不需要任何形式化的模型,而基于模型的則事先假定存在某個數(shù)據(jù)模型,并用EM算法試圖求出最相近的模型參數(shù)和簇的個數(shù)。
  • 基于密度的聚類
    將分布稠密的樣本劃分到同一個簇,并過濾低密度的區(qū)域。
    下面一一看下四種算法,并采用基于簇間距離平方和志平均側(cè)影寬度進行聚類內(nèi)部驗證,通過Ground truth方法完成聚類的外部驗證。

9.2 通過層次聚類處理數(shù)據(jù)

可以分成自底向上的凝聚(agglomerative)和自頂向下的分裂(divise)兩種。首先都要通過距離相似性來判斷對數(shù)據(jù)合并還是分裂處理。整個算法遞歸過程一直到全部歸并到一個簇或不可再分為止,最后系統(tǒng)樹圖展現(xiàn)聚類層次結(jié)構(gòu)。

# data
wget https://github.com/ywchiu/ml_R_cookbook/raw/master/CH9/customer.csv
# 只有60行,復(fù)制在這
ID,Visit.Time,Average.Expense,Sex,Age
1,3,5.7,0,10
2,5,14.5,0,27
3,16,33.5,0,32
4,5,15.9,0,30
5,16,24.9,0,23
6,3,12,0,15
7,12,28.5,0,33
8,14,18.8,0,27
9,6,23.8,0,16
10,3,5.3,0,11
11,4,8.6,0,13
12,14,21,0,25
13,12,28.5,0,33
14,7,16.1,0,16
15,4,17.4,0,9
16,6,4.6,0,21
17,14,23.6,0,22
18,8,15.9,0,19
19,17,25.9,0,18
20,8,20.4,1,39
21,7,10.9,1,17
22,14,33.7,1,17
23,3,5.6,1,12
24,18,21.1,1,26
25,12,30,1,28
26,3,4.8,1,12
27,6,9.1,1,11
28,9,29.4,1,32
29,5,10.2,1,17
30,1,4.5,1,8
31,10,10.9,1,17
32,12,25.4,1,27
33,13,25.5,1,36
34,13,20.1,1,26
35,1,4.5,1,8
36,4,11,1,12
37,10,27.6,1,41
38,4,12,1,23
39,7,10.6,1,15
40,7,10.9,1,17
41,3,8.3,1,8
42,7,16.1,1,16
43,7,11.5,1,19
44,9,15.6,1,21
45,11,24.9,1,25
46,9,29.4,1,32
47,6,23.8,1,16
48,5,14.9,1,17
49,7,15.1,1,21
50,18,21.1,1,26
51,3,5.3,1,11
52,10,17.8,1,29
53,15,27.9,1,23
54,8,12,1,22
55,9,19,1,20
56,3,7.2,1,15
57,13,25.2,1,47
58,8,11.3,1,22
59,6,8.1,1,10
60,11,26.3,1,45
# ###########聚類
customer <- read.csv('customer.csv', header = TRUE)
head(customer)
str(customer)
# 歸一化
customer <- scale(customer[,-1])
# 自底向上
hc <- hclust(dist(customer, method = "euclidean"), method = "ward.D2");hc
Call:
hclust(d = dist(customer, method = "euclidean"), method = "ward.D2")

Cluster method   : ward.D2 
Distance         : euclidean 
Number of objects: 60 
plot(hc, hang = 0.01, cex=0.7)

離差平方和ward.D2法聚類樹圖

single最短距離法

距離有最短距離、最長距離(complete linkage)、平均距離和最小方差法。
拓展

9.3 將樹分成簇

# 簇
fit <- cutree(hc,k=4)
fit
 [1] 1 1 2 1 2 1 2 2 1 1 1 2 2 1 1 1 2 1 2 3 4 3 4 3 3 4 4 3 4 4 4 3 3 3 4
[36] 4 3 4 4 4 4 4 4 4 3 3 4 4 4 3 4 3 3 4 4 4 3 4 4 3
table(fit)
fit
 1  2  3  4 
11  8 16 25 
plot(hc)
rect.hclust(hc,k=4, border = "red")
plot(fit)

紅框標(biāo)記不同簇

無意中畫了這個圖,也挺好

除了指定cutree函數(shù)中的簇個數(shù),還可以通過設(shè)置height值來指定聚類樹的高度,達到切割樹的目的。
拓展

# 單獨標(biāo)記某簇
plot(hc)
rect.hclust(hc,k=4,which =2,border = "red")
# 不同顏色不同簇 dendextend包
dend %>% color_branches(k=4) %>% plot(horiz=TRUE, main="Horizontal Dendrogram")
# 加紅框
dend %>% rect.dendrogram(k=4, horiz = TRUE)
image.png

水平聚類,彩框

分割線

9.4 使用k均值法處理數(shù)據(jù)

扁平聚類,一層劃分得到k簇,需要先確定簇個數(shù),效率優(yōu)于層次聚類。

# knn
set.seed(22)
fit <- kmeans(customer,4)
fit
# 簇中心條形圖
barplot(t(fit$centers),beside = TRUE, xlab = "cluster", ylab = "value")
# 簇散點圖
plot(customer, col=fit$cluster)
4簇不同屬性條形圖


分裂聚類,目的是使組內(nèi)平方和最小。還可以規(guī)定具體的聚類方法,如Hatigan-Wong, Lloyd, Forgy以及MacQueen。

9.5 繪制二元聚類圖

二元聚類將變量減少為兩個主要成分,再利用組件(軸線和橢圓)展示數(shù)據(jù)聚類的結(jié)果。

# 二元聚類
library(cluster)
clusplot(customer, fit$cluster, color = TRUE, shade = TRUE)
# 標(biāo)記并放大
par(mfrow=c(1,2))
clusplot(customer, fit$cluster, color = TRUE, shade = TRUE)
rect(0.5,-1.15,3,-0.4,border = "orange", lwd = 2)
clusplot(customer, fit$cluster, color = TRUE, xlim = c(0.5,3),
         ylim = c(-1.15,-0.4))


圖畫得有點累,找坐標(biāo)

拓展
clusplot使用了princomp和cmdscale兩個函數(shù)降維操作得到主成分

# cmdscale
par(mfrow=c(1,1))
mds <- cmdscale(dist(customer), k=2)
plot(mds,col=fit$cluster)
cmdscale MDS

9.6 聚類算法比較

可以使用簇內(nèi)距離或者簇間距離作為評判標(biāo)準(zhǔn),fpc包的cluster.stat函數(shù)

# 算法比較
install.packages("fpc")
library(fpc)
single_c <- hclust(dist(customer), method = "single") #層次聚類 最短距離法
hc_single <- cutree(single_c, k=4)
# 層次聚類 最長距離法
complete_c <-  hclust(dist(customer), method = "complete")
hc_complete <- cutree(complete_c, k=4)
set.seed(22)
# km均值
km <- kmeans(customer,4)
# 基本統(tǒng)計
cs <- cluster.stats(dist(customer), km$cluster)
cs[c('within.cluster.ss', 'avg.silwidth')]
# 列表顯示
sapply(list(kmeans=km$cluster, hc_single =hc_single, hc_complete=hc_complete), 
       function(c) cluster.stats(dist(customer), c)[c('within.cluster.ss', 'avg.silwidth')])
                  kmeans    hc_single hc_complete
within.cluster.ss 61.3489   136.0092  65.94076   #距離平方和,同一簇之間對象相關(guān)性,越小相關(guān)性越大
avg.silwidth      0.4640587 0.2481926 0.4255961 # 平均輪廓值,既考慮簇內(nèi)聚合又考慮簇間分離度

最長距離層次聚類優(yōu)于最短距離層次聚類和km算法。如下也可以輸出聚類統(tǒng)計信息:

km$withinss
[1] 20.89159  5.90040 22.58236 11.97454
km$betweenss
[1] 174.6511

9.7 從簇中抽取輪廓

輪廓系數(shù)取值0-1,越接近于1,聚類效果越好。

# 輪廓
kms <- silhouette(km$cluster, dist(customer))
summary(kms)
Silhouette of 60 units in 4 clusters from silhouette.default(x = km$cluster, dist = dist(customer)) :
 Cluster sizes and average silhouette widths:
       25         8        16        11 
0.5164434 0.5464597 0.3794910 0.4080823 
Individual silhouette widths:
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.1931  0.4030  0.4890  0.4641  0.5422  0.6333 
plot(kms)
k均值聚類對象輪廓

9.8 獲得優(yōu)化的k均值聚類

k均值算法效率高也易于實現(xiàn),可以使用距離平方和來確定哪個k值能實現(xiàn)最好的效果。

# 優(yōu)化km聚類
nk<- 2:10
set.seed(22)
# 每個簇距離平方和
WSS <- sapply(nk, function(k){
   kmeans(customer, centers = k)$tot.withinss
})
WSS
plot(nk,WSS,type = "l", xlab = "no. of k", ylab = "within sum of squares")
# 平均輪廓
SW<- sapply(nk, function(k){
   cluster.stats(dist(customer), kmeans(customer,centers = k)$cluster)$avg.silwidth
})
SW
plot(nk,SW, type = "l",xlab = "no. of k", ylab = "average ailhouette width")
nk[which.max(SW)]
[1] 4
不同k平方和線圖

不同k平均輪廓

9.9 使用密度聚類方法處理數(shù)據(jù)

將分布稠密和稀疏的樣本分開,DBSCAN是最著名的算法。

# 密度聚類
install.packages("mlbench")
library(mlbench)
install.packages("fpc")
library(fpc)
set.seed(2)
p <- mlbench.cassini(500)
plot(p$x)
ds <- dbscan(dist(p$x), 0.2,2,countmode=NULL,method="dist");ds # 可達距離0.2,最小可達點個數(shù)2,計算進度NULL,距離矩陣作為計算依據(jù)
dbscan Pts=500 MinPts=2 eps=0.2
        1   2   3
seed  200 200 100
total 200 200 100
plot(ds,p$x)
#預(yù)測
y<- matrix(0,nrow = 3, ncol = 2)
y[1,] <- c(0,0)
y[2,] <- c(0,-1.5)
y[3,] <- c(1,1)
y
     [,1] [,2]
[1,]    0  0.0
[2,]    0 -1.5
[3,]    1  1.0
#預(yù)測
y<- matrix(0,nrow = 3, ncol = 2)
y[1,] <- c(0,0)
y[2,] <- c(0,-1.5)
y[3,] <- c(1,1)
y
predict(ds,p$x,y)
[1] 3 1 2
Cassini問題圖

聚類結(jié)果彩色散點圖

兩個參數(shù)eps和MinPts,分別是最大鄰域半徑和鄰域半徑范圍內(nèi)的最小點數(shù)??梢哉{(diào)用fpc::plotcluster函數(shù)生成一個判別投影圖

9.10 基于模型的聚類方法

# ########模型
install.packages("mclust")
library(mclust)
mb <- Mclust(customer)
par(mfrow=c(1,1))
plot(mb)
summary(mb)
---------------------------------------------------- 
Gaussian finite mixture model fitted by EM algorithm 
---------------------------------------------------- 

Mclust VII (spherical, varying volume) model with 5 components: 

 log-likelihood  n df       BIC       ICL
      -220.7207 60 29 -560.1775 -561.8828

Clustering table:
 1  2  3  4  5 
11  8 17 17  7 
不同成分BIC

不同特征組合分類

不同組合分類不確定性

密度估計

基于概率的方法,而不啟發(fā)式構(gòu)建簇,假設(shè)服從某未知分布,并試圖找出這個分布,有限混合模型是一類常見的模型,單個模型分配線性權(quán)重再組合得到結(jié)果模型,提供一個靈活模型框架解釋數(shù)據(jù)分布概率。步驟是首先確定模型數(shù)量及概率分布類型,然后構(gòu)建并計算每個模型后驗概率,最后分配到概率最大類別。BIC用于選擇簇的個數(shù)。簇個數(shù)為5.

相異度矩陣的可視化

用來評估聚類的質(zhì)量,熱力圖可以實現(xiàn),相似的顏色深,如對角線。

# 相異度矩陣的可視化
install.packages("seriation")
library(seriation)
dissplot(dist(customer), labels = km$cluster, 
         options = list(main="Kmeans Clustering With K=4"))
dissplot(dist(customer), labels = hc_complete,
         options = list(main="Hierachical Clustering ") )

相異度矩陣圖

層次聚類

拓展
dist和image也可以實現(xiàn)image(as.matrix(dist(customer)))

heapmap當(dāng)然也可以

heatmap(customer,Rowv = as.dendrogram(hclust(t(dist(customer)))), Colv = as.dendrogram(hclust(dist(t(customer)))))

9.12 外部驗證評估

# 外部驗證
install.packages("png")
library(png)
img2 <- readPNG('handwriting.png',TRUE)
img3 <- img2[,nrow(img2):1]
b <- cbind(as.integer(which(img3 < -1) %% 28), which(img3 < -1)/28)
plot(b,xlim = c(1,28), ylim = c(1,28))
# km
set.seed(18)
fit <- kmeans(b,2)
plot(b,col=fit$cluster,xlim = c(1,28), ylim = c(1,28))
# dbscan
ds <- dbscan(b,2)
ds
plot(ds,xlim = c(1,28), ylim = c(1,28))
手寫數(shù)字散點圖

kmeans

dbscan

這里部分理解了計算機處理圖像的方式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 文章內(nèi)容主要摘自 https://blog.csdn.net/u011826404/article/details...
    一杭o(jì)neline閱讀 989評論 0 0
  • 關(guān)鍵字 Q1:分類和聚類有什么不同? 第一,它們面對的根本問題不同。分類的根本問題是判斷給定的某一個樣本屬于那一個...
    andyham閱讀 1,568評論 0 13
  • 1. 前言 聚類任務(wù)是無監(jiān)督學(xué)習(xí),無監(jiān)督學(xué)習(xí)的目標(biāo)是通過對無標(biāo)記訓(xùn)練樣本的學(xué)習(xí)來揭示數(shù)據(jù)的內(nèi)在性質(zhì)及規(guī)律,為進一步...
    Aptitude閱讀 647評論 2 0
  • 1. 章節(jié)主要內(nèi)容 “聚類”(clustering)算法是“無監(jiān)督學(xué)習(xí)”算法中研究最多、應(yīng)用最廣的算法,它試圖將數(shù)...
    閃電隨筆閱讀 5,306評論 1 24
  • 9.1 聚類任務(wù) 在無監(jiān)督學(xué)習(xí)任務(wù)中,包括了密度估計、異常檢測以及聚類等。其中應(yīng)用最廣泛的是聚類。 聚類就是對大量...
    D系鼎溜閱讀 1,227評論 0 1

友情鏈接更多精彩內(nèi)容