「Workshop」第十期:聚類

2021-02-20 優雅R

本期由吳濤師弟講解聚類,內容很詳實,推薦感興趣的讀者通過原文連結觀看介紹視頻。

聚類分析的思想:對於有p個變量的數據集來說,每個觀測值都是p維空間中的一個點,所以屬於同一類的點在空間中的距離應該顯著小於屬於不同類的點之間的距離

聚類距離測度

1.歐氏(Euclidean)距離:

2.曼哈頓(Manhattan)距離:

x,y都是n維的向量

還有一些不相似性度量也可以來表示距離:

3.Pearson線性相關距離:也就是1減去Pearson相關係數,Pearson相關是衡量兩個變量的線性相關性的,對數據的假設:Pearson相關係數應用於連續變量,假定兩組變量均為正態分布、存在線性關係且等方差

4.cosine相關距離:是Pearson相關的一個特例,就是將

5.Spearman相關距離:spearman相關計算的是變量秩之間的相關性,也是1減去Spearman相關係數

6.Kendall 相關距離:

Kendall相關方法是衡量變量秩的correspondence

對於大小是n的變量x和y,可能的匹配對數是

距離的選擇

如果我們關注的是變量的變化趨勢而不是變量的具體的值的時候,比如基因的表達,我們就可以使用基於相關性的距離測度,另外要注意的是pearson相關對outliers比較敏感,這個時候可以使用spearman相關

當我們關注的是變量的值的大小,可以使用歐氏距離來聚類

數據標準化

當變量是由不同的標度測量的時候,最好要對數據進行標準化使之可以進行比較;一般情況在下對變量進行縮放使之:標準差是1,均值是0;當變量的均值或者標準差相差較大的時候也可以對數據進行scale:

center(x)可以是均值或者中位數;scale(x)可以是標準差,四分位間距,或者絕對中位差(median absolute deviation,MAD),R裡面可以使用scale()函數進行標準化

MAD的定義:數據點到中位數的絕對偏差的中位數

❞計算距離矩陣

使用的數據集為USArrests:

df <- USArrestsdf_scaled <- scale(df)##標準化

計算距離的R函數有很多,如:

get_dist() factoextra包裡面的,可以計算基於相關性的距離,包括「pearson」, 「kendall」  「spearman」daisy()cluster包裡面的,可以處理除了數值變量以外的其他變量類型(如分類變量,定序變量等)

注意:這些計算距離的函數都是計算行之間的距離,所以如果我們要計算變量(列)之間的距離,先要將其轉置

dist.eucl <- dist(df_scaled,method = "euclidean")##歐氏距離class(dist.eucl)#[1] "dist"as.matrix(dist.eucl)[1:3,1:3]#         Alabama   Alaska  Arizona# Alabama 0.000000 2.703754 2.293520# Alaska  2.703754 0.000000 2.700643# Arizona 2.293520 2.700643 0.000000library(factoextra)dist_cor <- get_dist(df_scaled,method = "pearson")##相關性距離as.matrix(dist_cor)[1:3,1:3]#          Alabama    Alaska   Arizona# Alabama 0.0000000 0.7138308 1.4465948# Alaska  0.7138308 0.0000000 0.8307246# Arizona 1.4465948 0.8307246 0.0000000
library(cluster)data("flower")head(flower,3)# V1 V2 V3 V4 V5 V6 V7 V8# 1 0 1 1 4 3 15 25 15# 2 1 0 0 2 1 3 150 50# 3 0 1 0 3 3 1 150 50str(flower)# 'data.frame': 18 obs. of 8 variables:# $ V1: Factor w/ 2 levels "0","1": 1 2 1 1 1 1 1 1 2 2 ...# $ V2: Factor w/ 2 levels "0","1": 2 1 2 1 2 2 1 1 2 2 ...# $ V3: Factor w/ 2 levels "0","1": 2 1 1 2 1 1 1 2 1 1 ...# $ V4: Factor w/ 5 levels "1","2","3","4",..: 4 2 3 4 5 4 4 2 3 5 ...# $ V5: Ord.factor w/ 3 levels "1"<"2"<"3": 3 1 3 2 2 3 3 2 1 2 ...# $ V6: Ord.factor w/ 18 levels "1"<"2"<"3"<"4"<..: 15 3 1 16 2 12 13 7 4 14 ...# $ V7: num 25 150 150 125 20 50 40 100 25 100 ...# $ V8: num 15 50 50 50 15 40 20 15 15 60 ...dd <- daisy(flower)##計算含有分類變量,定序變量的距離as.matrix(dd)[1:3,1:3]# 1 2 3# 1 0.0000000 0.8875408 0.5272467# 2 0.8875408 0.0000000 0.5147059# 3 0.5272467 0.5147059 0.0000000

劃分聚類(Partitioning clustering)

劃分聚類需要我們指定類別的數量

最常用的有:

K-medoids clustering (PAM)K均值聚類

k表示我們想要數據聚成的類數,最終的結果是實現高的類內相似性和低的類間相似性

我們的目的就是使上式最小化

算法隨機選取k個點作為起始聚類中心(initial cluster centers)更新聚類中心:計算每個類的數據點的平均值作為新的聚類中心迭代3,4步,直到聚類狀態不再變化或者達到最大的迭代數目(R中默認是10)R
kmeans(x, centers, iter.max = 10, nstart = 1)

centers: 類數或者起始的距離中心,如果輸入的是一個數值的話則隨機選取x的行作為初始聚類中心nstart: 開始選擇隨機聚類中心的次數,比如nstart=5,則是開始隨機選擇5次k個聚類中心,最後選擇結果最好的

如何選擇最佳聚類數?

一個簡單的方法就是嘗試不同的聚類數目k,計算上面的total within sum of square;隨著聚類數目的增加WSS的趨勢一定會下降(最極端的情況就是每個點都是一個類),當k小於真實聚類數時WSS下降幅度會很大,而當k大於真實聚類數時,再增加k WSS的下降幅度會驟減,所以會存在一個拐點

library(factoextra)fviz_nbclust(df_scaled,kmeans,method = "wss")+  geom_vline(xintercept = 4,linetype=2)

image-20200720233852847

最佳聚類數為4:

set.seed(2020720)km_res <- kmeans(df_scaled,4,nstart = 25)print(km_res)
names(km_res)# [1] "cluster" "centers" "totss" "withinss" "tot.withinss"# [6] "betweenss" "size" "iter" "ifault"

結果包括聚類的中心點,每個觀測值所屬的類,wss

對於高維的數據我們可以先降維再可視化聚類的結果:

fviz_cluster(km_res, data = df_scaled)

image-20200720235320015K-Medoids

在k-medoids聚類中每個類由類內的某個點來代替,這些點就叫聚類中心(cluster medoids)

在 K-means 算法中,我們每次選簇的平均值作為新的中心,迭代直到簇中對象分布不再變化。因此一個具有很大極端值的對象會扭曲數據分布,造成算法對極端值敏感; K-Medoids算法不選用平均值而是用中心點作為參照點

最常用的k-medoids聚類方法是PAM算法(Partitioning Around Medoids)

PAM 算法隨機選擇k個點作為medoids(或者指定k個點)在每一類裡面,對除初始的medoids點外的所有其他點,按順序計算當其為新的medoids時準則函數的值是否下降,選擇使其下降最多的點作為新的中心點(準則函數為所有點到其最近中心點的距離的和)迭代3,4直到準則函數不再下降(medoids不再變化)R
cluster::pam(x, k, metric = "euclidean", stand = FALSE)

x : 可以是數值矩陣或者數據框,行是觀測,列是變量;也可以是距離矩陣metric : 計算距離的方法,可以是euclidean或者manhattan

首先需要估計最佳聚類數,可以使用平均輪廓法(average silhouette method),平均輪廓值越高說明聚類質量越好

可以使用factoextra包中的fviz_nbclust函數來計算:

fviz_nbclust(df_scaled,pam,method = "silhouette")+  theme_classic()

image-20200721222804298

最佳聚類數為2:

pam_res <- pam(df_scaled,2)names(pam_res)# [1] "medoids"    "id.med"     "clustering" "objective"  "isolation"  "clusinfo"  # [7] "silinfo"    "diss"       "call"       "data"

繼續使用fviz_cluster進行PCA降維後可視化聚類的效果:

fviz_cluster(pam_res, data = df_scaled)

image-20200721223407152CLARA聚類

CLARA (Clustering Large Applications)是k-medoids聚類的延伸,用來處理比較大的數據集

算法應用PAM算法找出每個亞數據集的中心點,分別將每個亞數據集的中心點應用到整個數據集計算所有數據點到最近中心點的距離和,保留最小距離和的亞數據集的中心點重複1,2步如果計算的距離和小於上次最小的距離和則用新的中心點代替原來的中心點直至中心點不再變化R
##generate dataset.seed(2020721)df <- rbind(cbind(rnorm(200,0,8), rnorm(200,0,8)),            cbind(rnorm(300,50,8), rnorm(300,50,8)))colnames(df) <- c("x","y")rownames(df) <- paste("S",1:nrow(df),sep = "")

cluster::clara(x, k, metric = "euclidean", stand = FALSE, samples = 5, pamLike = FALSE)

metric : 距離計算方法可以選擇euclidean或者manhattanpamLike:是否和pam()函數使用相同的算法

首先使用silhouette方法來估計最佳聚類數:

fviz_nbclust(df, clara, method = "silhouette")+  theme_classic()

image-20200721233550297

最佳聚類數為2:

clara_res <- clara(df,2,samples = 50,pamLike = T)print(clara_res)names(clara_res)# [1] "sample"     "medoids"    "i.med"      "clustering" "objective"  "clusinfo"  # [7] "diss"       "call"       "silinfo"    "data"

fviz_cluster(clara_res,data = df)

image-20200721234056740層次聚類(Hierarchical clustering)

層次聚類和劃分聚類一個顯著不同就是層次聚類不需要預先規定聚類數目

凝聚方法(agglomerative hierarchical clustering):自底向上,每個觀察值最初都被視為一類(葉),然後將最相似的類連續合併,直到只有一個大類(根)為止分裂方法(divisive hierarchical clustering):自上向下,是凝聚聚類的逆過程,從根開始,所有觀測值都包含在一個類中然後將最不均一的聚類相繼劃分直到所有觀測值都在它們自己的類中(葉)image-20200722083259840凝聚聚類使用連接函數(linkage function)基於距離信息將對象連接成層次聚類樹

連接函數獲取由函數dist()返回的距離信息,並根據對象的相似性將對象對分組;重複此過程,直到原始數據集中的所有對象在層次樹中連結在一起為止

res_hc <- stats::hclust(d = dist.eucl, method = "ward.D2")

method: 連接函數,可以是「ward.D」, 「ward.D2」, 「single」,「complete」, 「average」, 「mcquitty」, 「median」 「centroid」

主要使用的連接函數(也就是類間距離)有:

最長距離法(complete-linkage):兩個類的距離定義為兩個類的元素的所有成對距離的最大值最短距離法(single-linkage): 兩個類的距離定義為兩個類的元素的所有成對距離的最小值類平均法(mean or average linkage,UPGMA):  兩個類的距離定義為兩個類的元素的所有成對距離的平均值中心法(centroid linkage,UPGMC): 兩個聚類之間的距離定義為兩個類的質心(centroid,該類所有點的均值)的距離Ward法: 最小化總的within-cluster variation
plot(res_hc)fviz_dend(res_hc, cex = 0.5)

image-20200722133701585

連接兩個對象的豎線的高度衡量了這兩個對象的距離,越長距離越大,這個高度也叫這兩個對象的共同距離cophenetic distance

兩個點的共同距離是這兩個點第一次被聚在一起時的節點的高度,截取一小部分說明:

image-20200725182546137

我們可以看聚類樹的共同距離和原始的距離矩陣的相似性來衡量聚類的好壞:

res_coph <- cophenetic(res_hc)cor(dist_eucl, res_coph)#[1] 0.6975266
res_hc2 <- hclust(dist_eucl, method = "average") ##類平均法cor(dist_eucl, cophenetic(res_hc2))#[1] 0.7180382

可以使用cutree函數來分割樹進行聚類結果的展示:

cluster <- cutree(res_hc, k = 4)table(cluster)# cluster# 1  2  3  4 # 7 12 19 12 
factoextra::fviz_dend(res_hc, k = 4,rect = TRUE)##可視化
fviz_cluster(list(data = df_scaled, cluster = cluster))##先PCA再展現聚類結果

image-20200722133714891image-20200722133728396

另外cluster包也可以很方便的進行凝聚或者分裂聚類:

library("cluster")# Agglomerative res.agnes <- agnes(x = USArrests, # data matrix                   stand = TRUE, # Standardize the data                   metric = "euclidean", # metric for distance matrix method = "ward" # Linkage method)# Divisiveres.diana <- diana(x = USArrests, # data matrix                   stand = TRUE, # standardize the data                   metric = "euclidean" # metric for distance matrix )

比較樹狀圖

使用dendextend包

首先創建兩個不同的樹狀圖:

dend1 <- stats::as.dendrogram(res_hc) dend2 <- stats::as.dendrogram(res_hc2)dend_list <- dendextend::dendlist(dend1, dend2)dendextend::tanglegram(dend1, dend2)

image-20200722135343171

比對的質量可以使用entanglement()函數來計算,這個值是0到1之間的,越小說明比對越好

dendextend::entanglement(dend1, dend2)#[1] 0.8342094

也可以使用cor.dendlist()函數來計算兩個樹的相關性,有兩種方法cophenetic和baker

# Cophenetic correlation matrixdendextend::cor.dendlist(dend_list, method = "cophenetic")#          [,1]     [,2]# [1,] 1.000000 0.843143# [2,] 0.843143 1.000000# Baker correlation matrixdendextend::cor.dendlist(dend_list, method = "baker")#           [,1]      [,2]# [1,] 1.0000000 0.8400675# [2,] 0.8400675 1.0000000

選擇最佳聚類數直接法:最優化一個準則,比如within cluster variation(肘方法,elbow method)或者平均輪廓(輪廓法,silhouette method)

將總的WSS看做是聚類數的函數,當增加聚類數不會大幅度降低WSS時會出現一個拐點,選擇該點作為最佳聚類數

Average silhouette method(平均輪廓法)

該方法需要計算輪廓係數:

計算對象i到同類其他對象的平均距離

image-20200722142645591

「所有樣本的

和肘方法相似,計算不同聚類數目的輪廓係數,輪廓係數最大的聚類數為最佳聚類數

一般選擇B=500,結果就比較穩健

R
factoextra::fviz_nbclust(x, FUNcluster, method = c("silhouette", "wss", "gap_stat"))

FUNcluster: 聚類方法包括kmeans, pam, clara 和 hcut
# Elbow methodp1 <- factoextra::fviz_nbclust(df_scaled, kmeans, method = "wss") +   geom_vline(xintercept = 4, linetype = 2)+  labs(subtitle = "Elbow method")# Silhouette methodp2 <- factoextra::fviz_nbclust(df_scaled, kmeans, method = "silhouette")+   labs(subtitle = "Silhouette method")# Gap statistic# nboot = 50 to keep the function speedy.# recommended value: nboot= 500 for your analysis.# Use verbose = FALSE to hide computing progression.set.seed(123)p3 <- factoextra::fviz_nbclust(df_scaled, kmeans, nstart = 25, method = "gap_stat", nboot = 50)+  labs(subtitle = "Gap statistic method")cowplot::plot_grid(p1,p2,p3)

image-20200722144751617

NbClust包的NbClust()函數可以提供30種指標來計算最佳聚類數

 NbClust(data = NULL, diss = NULL,          distance = "euclidean", min.nc = 2, max.nc = 15, method = NULL)

diss:不相似矩陣,如果提供diss,後面的distance應該為NULLdistance: 計算距離矩陣的方法包括euclidean manhattan和NULLmethod: 聚類方法"ward.D", "ward.D2", "single", "complete", "average", "mcquitty", "median", "centroid", "kmeans"
nb <- NbClust::NbClust(df_scaled, distance = "euclidean", min.nc = 2,              max.nc = 10, method = "kmeans")factoextra::fviz_nbclust(nb)

image-20200722145610875

還有一個增強版的hclust:fastcluster::hclust:更快,能處理更大的數據

image-20200722150942964

參考:

https://cran.r-project.org/web/packages/flashClust/index.html

https://www.biostars.org/p/85150/

https://www.cnblogs.com/lexus/archive/2012/12/13/2815769.html

Kassambara A. Practical guide to cluster analysis in R: Unsupervised machine learning[M]. Sthda, 2017.

Reference[1]

R 聚類圖書: r-cluster-book.pdf

相關焦點

  • 「R」層次聚類和非層次聚類
    ❝原英文連結:https://www.rpubs.com/dvallslanaquera/clustering[1]❞層次聚類 (HC)在這個分析中,我們將看到如何創建層次聚類模型。目的是探索資料庫中是否存在相似性組,並查看它們的行為。
  • 人人都能讀懂的無監督學習:什麼是聚類和降維?
    機器之心在這裡編譯了這一系列文章的第三部分「無監督學習」,對主要的聚類和降維算法進行了介紹,其中包括 K 均值聚類、層次聚類、主成分分析(PCA)和奇異值分解(SVD)。機器之心將逐步向讀者介紹該系列更多的文章。我們可以怎樣發現一個數據集的底層結構?我們可以怎樣最有用地對其進行歸納和分組?我們可以怎樣以一種壓縮格式有效地表徵數據?
  • 「世界一初戀」2期決定!「Hybrid Child」動畫企劃中!
    沒錯,由中村春菊老師繪製的BL漫畫「Hybrid Child」將被動畫化了!並且同樣由她擔任漫畫版繪製的「世界一初戀」在第一期動畫完結之後,其第二期也製作決定了!   「世界一初戀」動畫:donghua.178.com/donghua_info/1520.html
  • 關於「十二元會」與冰河期
    問: 道中所謂「十二元會」之說,本出自邵康節「皇極經世」一書,所謂十二萬九千六百年之數,與天地人三才依序化育等學說,與現今地球壽命四十七億年之數難以相湊,然道場中每剖析三期末劫與三寶道統之沿革時,多以此說為基礎,若驗證於科學根據不知該如何解釋?
  • 回歸、分類與聚類:三大方向剖解機器學習算法的優缺點(附Python和R...
    沒有免費午餐定理在機器學習中,有個定理被稱為「沒有免費的午餐」。簡而言之,就是說沒有一個算法可以完美解決所有問題,而且這對於監督學習(即對預測的建模)而言尤其如此。舉個例子,你不能說神經網絡就一定任何時候都比決策樹優秀,反過來也是。這其中存在很多影響因素,比如你數據集的規模和結構。
  • 「行攝天下」第03期:我國最大的死火山島——潿洲島風光
    橫屏看大圖:本期圖/文:張飛躍往期回看:「行攝天下」第01期:省美麗鄉村示範村陳家橋的油菜花開了!「行攝天下」第02期:走,到道林古鎮坐火車看油菜花去!
  • 《超級機器人大戰T》第十話SR怎麼達成 第十話SR達成方法
    」同時擊墜2臺以上的敵機。這個條件是比較難的,今天小編就給大家帶來玩具「やなぎ しゅう」分享的第十話S... 《超級機器人大戰T》的第十話新吉翁的陰影想要達成SR就需要在完成關卡前使用撫子B的地圖炮「重力波炮」同時擊墜2臺以上的敵機。
  • 韓家煒在數據挖掘上開闢的「小路」是什麼
    例如將 NY Times 的新聞放入到這樣一個 Cube 中,我們想要總結「2016」、「China」、「Economy」的信息。與這些關鍵詞相關的 Documents 有很多很多,沒有人原意去一個一個地查看。如果只是簡單地用統計的方法來獲取信息,就會發現有很多不是「Economy」的信息,例如「Hong Kong」、「United States」等。
  • 逾越節和第十災什麼關係?
    但這並不表示它不是源起於某個已經存在的節期。應該回想的一點,是神設立為立 * 約證據的 * 割禮,也是個已經基於別種理由而存在的習俗。逾越節 * 儀式中很多環節,都似乎是取材自遊牧民族中,謀求保障牧民不受邪靈攻擊,和保證牲畜 * 豐饒的一種 * 儀式。即使如此,這些環節都經過成功的「改裝」,來切合第十災和出埃及的新背景。
  • 觀點| NIPS 2017經典論文獎獲得者機器學習「鍊金術」說引熱議,Le...
    我希望我所生活的世界是基於非常穩固、有規律的、理論性的知識之上的——而不是鍊金術之上。」「過去 NIPS 大會上經常出現的『學術警察』在哪裡?我非常懷念他們。」……「我們現在是這樣構建新知識的:我們應用最好的工具,簡單地分析自己做的設置,我們學習現象,然後在自己不理解背後原理的情況下完成了研究。就這麼完成了。」
  • 「遊戲王決鬥連結DL卡組」十代印卡技能,直接打臉真爽
    目錄活動說明技能分析關鍵卡分析在【遊戲王決鬥連結】最新活動「決鬥者年代記 GX」中擊敗決鬥王武藤遊戲即可獲得遊城十代專屬技能「英雄閃光」,此技能屬於十代的印卡技能,每2個回合額外獲得一張強力魔法卡,效果十分香。技能分析:「英雄閃光!!」
  • 「山系」露營老司機必備十件套
    本文經太格有物授權轉載,原標題:FUJI Select|「山系」露營老司機必備十件套,作者:日本印象志 (更多互動,請關注:thetigerhood 公眾號),文章內容僅代表作者觀點,與本站立場無關,未經允許請勿轉載。露營文化在國內越來越受到歡迎,成為很多人在閒暇時間的主要休閒方式。
  • 彩票市場進入了「小冰河期」
    既有讓許多物種滅絕的大冰河期,也有給人類社會帶來災難的小冰河期。小冰河期雖然不會造成物種滅絕的嚴重災難,但氣候惡劣造成災年,不僅對人類形成威脅,甚至會造成朝代更替。 彩票市場似乎從2014年起就進入了一個「小冰河期」。熱度一年年降低,購彩者的理性程度逐年增加,彩票銷量也從前些年的快速增長,變為增速放緩甚至出現下滑。尤其,去年的疫情以及政策調整的雙重影響疊加,年銷量一定會呈現出新的下跌曲線。
  • 肉番動畫「出包王女Darkness」系列第二期製作決定!
    肉番動畫「出包王女Darkness」系列第二期製作決定!   從2010年起,在「JUMP
  • 「機器學習」機器學習算法優缺點對比(匯總篇)
    「優點」:實現簡單,計算簡單;「缺點」:不能擬合非線性數據.最近鄰算法——KNNKNN即最近鄰算法,其主要過程為:1.「人工神經網絡應用領域:」目前深度神經網絡已經應用與計算機視覺,自然語言處理,語音識別等領域並取得很好的效果。K-Means聚類是一個簡單的聚類算法,把n的對象根據他們的屬性分為k個分割,k< n。
  • 《神魔之塔》「背城之旅龍.藍託」戰慄級任務展開 競技場「朗傑...
    此外,競技場角色「見習魔導士.朗傑」即將開放進化成火屬性的「顛世的魔音.朗... 《神魔之塔》16.0 版本即進踏進第六週,營運團隊宣布「背城之旅龍.藍託」即將壓軸出場,為召喚師帶來「巨龍的追憶」戰慄級任務。此外,競技場角色「見習魔導士.朗傑」即將開放進化成火屬性的「顛世的魔音.朗傑」。
  • 第62回小學館漫畫賞「BLUE GIANT」、「靈能百分百」等獲獎!
    第62回小學館漫畫賞「BLUE GIANT」、「靈能百分百」等獲獎!獲獎,少女向的作品中椎名千花的「37.5℃的淚」獲獎,少年向的作品中ONE的「靈能百分百」獲獎,兒童向的作品中五十嵐かおる的「いじめ」(欺凌)獲獎。
  • 動畫「天地無用!魎皇鬼」第五期追加STAFF情報公開
    動畫「天地無用!魎皇鬼」第五期追加STAFF情報公開 動漫 178動漫原創 ▪ 2019-08-09 11:16:07
  • 「黎明拾穗」37期詩詞30首,夜色朦朧月作燈,照明池水看雲騰
    3、收稿時間2020年7月12日「黎明拾穗」37期詩詞28首1七絕·小暑遇暴雨(新韻)作者:艾曉東暴雨翻盆澆小暑,雷公作賦句驚天「黎明拾穗」36期,44位詩人為高考寫詩加油「黎明拾穗」35期詩詞25首,同窗聚會話鋒長,唯有班花政務忙
  • 春季動畫「聆聽者」第7話「憤怒之日」的先行鏡頭髮布!
    春季動畫「聆聽者」第7話「憤怒之日」的先行鏡頭髮布! 動漫 178動漫整編 ▪ 2020-05-10 16:02:18 每周五播出的「聆聽者」這次公開了5月15日(周五)播出的第7話「憤怒之日」的梗概和先行剪輯