模糊c均值聚類(FCM)及其在R中實現

2022-01-10 小白魚的生統筆記
先前所簡介的層次聚類、劃分聚類等,所產生的聚類簇都是非重疊的實體,即對於每個對象而言只有一個確定的分類,這種聚類方法也成硬聚類(hard-clustering)。相比之下,模糊聚類(fuzzy clustering,或稱軟聚類,soft-clustering)是涉及對象之間的模糊界限時按一定要求對對象分類的數學方法,用於定量地確定對象間的親疏關係,達到客觀準確的分類目的(Bezdek, 1981)。聚類根據對象之間的相似度將對象分成組,使組內對象儘可能相似(或距離短),組間儘可能不同(距離大)。模糊聚類產生的聚類簇的界限不明顯,一個對象具有屬於多個類的可能性,在描述對象分類時更加謹慎,更貼合自然界的實際情況。在計算上,創建模糊邊界也比在一個類中為一個對象確定邊界容易得多。模糊聚類類似於原子軌道和電子行為:電子不處於固定的位置,而是有可能出現在特定軌道殼中,如果將軌道殼視為「聚類簇」,將電子視為「對象」,那麼這種可能性就是將對象分配到特定簇的概率。

   

模糊c均值聚類(Fuzzy C-Means Clustering,FCM)是最廣泛使用的模糊聚類算法之一,與k均值劃分聚類較為相似,通過不斷迭代使組內平方和最小化。二者最主要的區別在於,k均值劃分聚類中每個對象只由一個聚類中心約束,模糊c均值聚類中對象與所有聚類中心都有關。

組內平方和計算如下:


其中uijm通過下式計算:


uij是對象xi屬於簇cj的程度,與對象xi離cj質心(聚類中心)的距離成反比;uj是簇j的質心。模糊c均值聚類中,一個對象理論上可以被分配為所有組,並通過給定對象在各組中的成員值(membership value)描述對象屬於某一類的程度(可以理解為概率)。成員值介於0和1之間,接近0代表了對象遠離該聚類中心,接近1代表對象靠近該聚類中心,每個對象在各類中成員值的總和為1。

聚類中心計算為組內所有對象的質心,並根據對象的成員度進行加權。


m是模糊參數,理論上可以取大於或等於1的任何值,當接近於1時聚類結果將與k均值劃分等硬聚類相似,值接近無限將導致完全模糊,通常使用m=2。

 

模糊c均值聚類過程可以總結如下:

(1)指定聚類數k;

(2)為每個對象任意分配一組初始成員值;

(3)使用上述公式計算每個聚類簇的質心;

(4)使用上述公式重新計算每個對象在各聚類簇中的成員值;

(5)重複(3)、(4)過程,直到成員值收斂(不再變動)或達到最大迭代次數為止。

 

由於在計算方式上與k均值劃分聚類具有類似點,因此也可能存在相似的問題:聚類結果受初始k的數量影響顯著;不同的初始化配置可能導致不同的結果;如果到達最大迭代次數時仍未收斂,則可能會陷入局部最小值。

接下來展示R語言執行模糊c均值聚類的方法。

示例數據和R代碼的百度盤連結:

https://pan.baidu.com/s/1KjnCaP4Gfdys9lSrw5mUUA

cluster包提供了模糊c均值聚類方法,通過函數fanny()實現。

library(cluster)
 
#示例數據包含 15 個樣本(對象),20 個變量
dat <- read.delim('data.txt', sep = '\t', row.names = 1, stringsAsFactors = FALSE, check.names = FALSE)
#推薦變量標準化,主要用於消除量綱差異,降低極端值比重
dat <- scale(dat)
 
#已知這些樣本來自於 3 組數據,但不明確具體哪些樣本是一組的,用來演示模糊 c 均值聚類過程
#模糊 c 均值聚類,詳情 ?fanny
set.seed(123)
cm.fanny <- fanny(dat, k = 3, metric = 'euclidean', maxit = 100)
cm.fanny
 
#或者也可計算對象間距離,將距離作為模糊 c 均值聚類的輸入,不使用原始數據
dis_euc <- vegan::vegdist(dat, method = 'euclidean')
set.seed(123)
cm.fanny <- fanny(dis_euc, k = 3, diss = TRUE, maxit = 100)
cm.fanny
 
#查看主要結果
names(cm.fanny)
 
head(cm.fanny$membership)    #對象屬於某一類的程度,即成員值,行和為 1
cm.fanny$clustering    #最佳分類,即各對象最接近的聚類簇

#輪廓圖
plot(silhouette(cm.fanny))


輪廓圖顯示對象分類為3組的情況良好。

 

將模糊c均值聚類和排序圖(如PCoA)結合,觀測對象之間的整體相似性或差異,以及識別的分類特徵。

#以 PCoA 為例降維,並將聚類結果標註在排序圖中
#以上述所得對象間歐幾裡得距離為例,計算 PCoA
pcoa <- cmdscale(dis_euc, k = (nrow(dat) - 1), eig = TRUE)
eig_prop <- 100*pcoa$eig/sum(pcoa$eig)
pcoa_site <- pcoa$point[ ,1:2]
plot(pcoa_site,
xlab = paste('PCoA axis1:', round(eig_prop[1], 2), '%'),
ylab = paste('PCoA axis2:', round(eig_prop[2], 2), '%'))

#標註各對象最接近的聚類簇
for (i in 1:3) {
gg <- pcoa_site[cm.fanny$clustering == i, ]
hpts <- chull(gg)
hpts <- c(hpts, hpts[1])
lines(gg[hpts, ], col = 1+1)
}

#星圖展示了各對象的成員值
stars(cm.fanny$membership, location = pcoa_site, draw.segments = TRUE,
add = TRUE, scale = FALSE, col.segments = 2:4, len = 0.5)


星圖展示了對象屬於各聚類簇的成員值,面積越大代表成員值越高,並將各對象所屬的最佳聚類簇用紅線連接。數據集整體特徵一目了然。

 

相比上述plot()作圖,factoextra包提供了更便捷的方法,以下是一些參考。

#factoextra 包的可視化方案
library(factoextra)

#聚類和 PCA 結合,點的顏色和形狀代表分組,分組橢圓展示為 95% 置信區間
fviz_cluster(cm.fanny, ellipse.type = 'norm', repel = TRUE, palette = 'jco',
ellipse.level = 0.95, ggtheme = theme_minimal(), legend = 'right')

#輪廓圖
fviz_silhouette(cm.fanny, palette = 'jco', ggtheme = theme_minimal())

e1071包也是可用於模糊c均值聚類的常用R包,繼續使用上文的示例展示e1071包中的方法。

做過表達譜時間趨勢分析的同學們可能用過一個R包,Mfuzz,它就是以e1071包中的模糊c均值方法為基礎進行時間表達模式聚類的。

library(e1071)

#讀取數據
dat <- read.delim('data.txt', sep = '\t', row.names = 1, stringsAsFactors = FALSE, check.names = FALSE)
#推薦標準化,主要用於消除量綱差異,降低極端值比重
dat <- scale(dat)

#模糊 c 均值聚類,詳情 ?cmeans
#期望分為 3 類,最大迭代 100 次
set.seed(123)
cm.cmeans <- cmeans(dat, centers = 3, iter.max = 100, dist = 'euclidean', method = 'cmeans')
cm.cmeans

#查看主要結果
summary(cm.cmeans)

head(cm.cmeans$membership) #對象屬於某一類的程度,即成員值,行和為 1
cm.cmeans$cluster #最佳分類,即各對象最接近的聚類簇

 

可以結合一些其它包的可視化方法,觀測對象分類詳情。

#使用 corrplot 包描述對象歸屬的成員值
library(corrplot)

corrplot(cm.cmeans$membership, is.corr = FALSE)


該圖代表了模糊c均值聚類計算的各對象在各類別中的歸屬程度,明確屬於某一聚類簇的對象在該簇中具有較高的成員值。

同樣地,再結合排序圖觀測各類別的邊界,將聚類結果標註在圖中。

#factoextra 包的可視化方案,和 PCA 結合
#點的顏色和形狀代表分組,分組橢圓展示為 95% 置信區間
library(factoextra)
fviz_cluster(list(data = dat, cluster = cm.cmeans$cluster), palette = 'jco',
ellipse.type = 'norm', ellipse.level = 0.95, ggtheme = theme_minimal())


不同顏色和形狀的點代表對象屬於不同的類別,各組中心最大的點代表了聚類中心,顯示該示例數據的樣本分類還是很好的。

https://www.datanovia.com/en/lessons/fuzzy-clustering-essentials/fuzzy-c-means-clustering-algorithm/https://www.datanovia.com/en/lessons/fuzzy-clustering-essentials/cmeans-r-function-compute-fuzzy-clustering/Bezdek J C. 1981. Pattern Recognition with Fuzzy Objective Function Algorithms. New York: Plenum Press.

相關焦點

  • MATLAB之FCM模糊k-means算法
    對Kmeans方法相信大家都會不陌生,這是一種廣泛被應用的基於劃分的聚類算法。Kmeans雖然簡單實用,但是對於一些實際問題在功能上還是略顯遜色,同時它還有一個先天的不足,那就是它是一種硬性的劃分方法。FCM算法是對硬性劃分的一種改進,其核心思想如下:FCM把n個向量xi(i=1,2,…,n)分為c個模糊組,並求每組的聚類中心,使得非相似性指標的價值函數達到最小。
  • R語言做K均值聚類的一個簡單小例子
    參考連結https://www.guru99.com/r-k-means-clustering.htmlhttps://datascienceplus.com/k-means-clustering-in-r/https://www.datanovia.com/en/lessons/k-means-clustering-in-r-algorith-and-practical-examples
  • 不足 20 行 Python 代碼,高效實現 k-means 均值聚類算法!
    k-means均值算法雖然是聚類算法中比較簡單的一種,卻包含了豐富的思想內容,非常適合作為初學者的入門習題。關於 k-means 均值聚類算法的原理介紹、實現代碼,網上有很多,但運行效率似乎都有點問題。今天稍微有點空閒,寫了一個不足20行的 k-means 均值聚類算法,1萬個樣本平均耗時20毫秒(10次均值)。同樣的數據樣本,網上流行的算法平均耗時3000毫秒(10次均值)。
  • 【源碼】基於FCM和FSC的模糊RBFNN性能研究
    該代碼使用RBFNN的模糊擴展,使用模糊c均值聚類和模糊監督進行分類。
  • 有了K均值聚類,為什麼還需要DBSCAN聚類算法?
    所有聚類法都使用相同的方法,即首先計算相似度,然後使用相似度將數據點聚類為組或群。本文將重點介紹具有噪聲的基於密度的聚類方法(DBSCAN)。既然已經有了K均值聚類,為什麼還需要DBSCAN這樣的基於密度的聚類算法呢?K均值聚類可以將鬆散相關的觀測聚類在一起。
  • 人工智慧算法|K均值聚類算法Python實現
    以下是K均值法的python代碼實現。程序使用的工具包括numpy和matplotlib,其中numpy是一個用於處理多維數組的庫,而Matplotlib 則用於繪製二維圖形。calcuDistance(vec1, vec2):    return numpy.sqrt(numpy.sum(numpy.square(vec1- vec2)))def loadDataSet(inFile):    # 載入數據測試數據集    # 數據由文本保存,為二維坐標    inDate = codecs.open(inFile, 'r'
  • R語言實現聚類kmeans
    ,為組內的所有數據樣本的均值。這裡其實就要對聚類的穩定性進行判斷了,有可能是聚類迭代次數過少,就會出現不同的聚類結果,就需要增加迭代次數,達到每次計算結果是一致的。也有可能是因為不同的包,實現的代碼有所區別導致的。k-means算法,也有一些缺點就是對於孤立點是敏感的,會被一些極端值影響聚類的效果。一種改進的算法是PAM,用於解決這個問題。
  • 基於R語言的Kmeans聚類算法
    本節介紹一下Kmeans聚類,也叫K均值聚類或者是動態聚類法。k-means算法也屬於無監督學習的一種聚類算法。採用R語言詳細描述Kmeans實現過程。      這種聚類方法的優勢在於,對於大樣本的聚類,具有計算量小,佔用計算機內存較少和方法簡單的優點。
  • 使用Python進行K均值聚類
    在機器學習中,當我們要處理一個未標記的數據集時,稱為「無監督學習」。有時我們只是想知道我們的數據是如何組織起來的這樣我們就能知道數據是如何組織起來的。聚類意味著對一組對象進行分組。>m =訓練實例數idx C(i)=已將實例X(i)分配給聚類的聚類質心看一個示例,使您可以清楚地看到此符號聚類分配步驟:在此步驟中,我們將根據數據集中最接近的聚類質心向數據集中分配一個聚類質心
  • 吳恩達《Machine Learning》精煉筆記 8:聚類 KMeans 及其 Python實現
    :聚類和降維。本文中首先介紹的是聚類中的K均值算法,包含:算法思想圖解K-Meanssklearn實現Python實現無監督學習unsupervised learning無監督學習簡介聚類和降維是無監督學習方法,在無監督學習中數據是沒有標籤的。
  • 圖解機器學習-聚類(k均值)
    在無監督學習中,樣本的標記是未知的,聚類任務的目標就是將數據集中的樣本劃分為若干個通常不相交的子集,通過對無標記樣本的訓練來發現數據的內在性質和隱性的規律。聚類的相似性度量歐氏距離(Euclidean Distance)是聚類相似性計算距離的一種方法,來自幾何數學中計算兩點間的距離公式。
  • k均值聚類算法原理和(TensorFlow)實現(無師自通)
    顧名思義,k均值聚類是一種對數據進行聚類的技術,即將數據分割成指定數量的幾個類,揭示數據的內在性質及規律。
  • ...分類與聚類:三大方向剖解機器學習算法的優缺點(附Python和R實現)
    Python 實現:http://scikit-learn.org/stable/modules/naive_bayes.htmlR 實現:https://cran.r-project.org/web/packages/naivebayes/index.html3、聚類聚類是一種無監督學習任務,該算法基於數據的內部結構尋找觀察樣本的自然族群(即集群)。
  • 機器學習中五種常用的聚類算法
    在數據科學中聚類會從數據中發掘出很多分析和理解的視角,讓我們更深入的把握數據資源的價值、並據此指導生產生活。以下是五種常用的聚類算法。 K均值聚類 這一最著名的聚類算法主要基於數據點之間的均值和與聚類中心的聚類迭代而成。它主要的優點是十分的高效,由於只需要計算數據點與劇類中心的距離,其計算複雜度只有O(n)。
  • K-means 聚類算法及其代碼實現
    K-means算法是非監督學習(unsupervised learning)中最簡單也是最常用的一種聚類算法,具有的特點是:本文章介紹
  • 三種聚類方法的介紹及其R語言實現
    聚類分析法是研究「物以類聚」的一種現代統計分析方法,在眾多的領域中,都需要採用聚類分析作分類研究。聚類分析的類型包括兩種Q型聚類(對樣品聚類)、R型聚類(對變量聚類)。一、聚類分析介紹聚類分析方法包括很多種,例如:系統聚類法、動態聚類法、模糊聚類法、密度聚類法等,本文主要介紹的是系統聚類法、動態聚類法與密度聚類法。
  • K均值聚類算法-Matlab代碼
    一、K均值聚類算法算法步驟如下:1、初始化已知數據集合X,及事先指定聚類的總類數N,在X中隨機選取N個對象作為初始的聚類中心。5、重複步驟3~4,滿足步驟2中的迭代終止條件時,停止Matlab代碼見下圖:K均值聚類算法-Matlab代碼二、K均值聚類算法應用舉例1、隨機生成三組數據隨機生成的三組數據
  • 純Python實現k-means聚類算法
    開篇在本系列的前面幾期中,我們介紹了包含決策樹及其相關算法在內的一系列有監督學習算法。本期不妨換換口味,學習一種比較簡單的無監督學習算法:k-means.我們知道,在屬於有監督學習的分類問題中,訓練數據往往會包含類別標籤。而上面這份數據本身是不含標籤的,所以這並不是一個分類問題。既然不知道類別標籤,你又讓我對這些樣本進行分類,那如何聚類?又要聚成幾類呢?
  • R語言之實現K-mean聚類算法
    聚類算法作為無監督的學習方法,在不給出Y的情況下對所有的樣本進行聚類。以動態聚類為基礎的K均值聚類方法是其中最簡單而又有深度的一種方法。
  • 如何正確使用「K均值聚類」?
    聚類算法中的第一門課往往是K均值聚類(K-means),因為其簡單高效。本文主要談幾點初學者在使用K均值聚類時需要注意的地方。