作者: 于餅喵
閱讀時間:10min
有時我們需要將樣本按照特征分為不同的類,比如格嗅,金融機構需要根據(jù)客戶的特征將客戶劃分不同的等級番挺,這時聚類算法可以滿足我們的需求
本章主要介紹兩類常用聚類分析方法:
- 層次聚類(eg. Hierachical Clustering)
- 劃分聚類 (eg. K-means Clustering)
層次聚類和劃分聚類的區(qū)別在于是否提前指定了類別數(shù)量k,一般層次聚類用于找出最優(yōu)的分類數(shù)目k吗浩,而劃分聚類用于將觀測值劃分為給定k個類別
16.1 聚類分析一般步驟
- 挑選變量:挑選出用于聚類算法的特征(變量)建芙。比如:通過皮爾斯相關系數(shù)剔除相關性高的變量
-
標準化數(shù)據(jù):將特征的值標準化為均值為0,方差為1的變量懂扼,在R中,可以使用
scale()
函數(shù)來標準化數(shù)據(jù) -
處理異常值:層次聚類對異常值比較敏感右蒲,異常值有可能會改變最終的聚類方案阀湿,因此,使用層次聚類算法時去除異常值是必要的瑰妄。在R中陷嘴,可以使用
outliers
包中的函數(shù)moveliers()
來去除異常單變量離群點 - 計算距離:聚類算法的原理是通過距離來對不同的樣本進行分類,因此距離的計算尤為重要间坐。一般選擇歐式距離或者曼哈頓距離
- 選擇聚類算法:若樣本量較小灾挨,且不確定分類的數(shù)量k,則可以使用層次聚類竹宋;若已經根據(jù)業(yè)務得出了明確的分類數(shù)量k劳澄,可使用劃分聚類; 也可使用層次聚類得出最優(yōu)分類數(shù)目k后,再使用劃分聚類進行劃分(two-step clustering)
- 驗證最終分類結果是否顯著
- 分類結果的描述和可視化
16.2 距離(distance)
聚類分析使用距離來反映兩個樣本的相似性
兩個樣本之間的距離公式可以定義為:
當s為2時蜈七,公式為歐式距離(Euclidean Distance)秒拔,當s為1時,公式為曼哈頓距離飒硅。一般常用歐式距離
在R中砂缩,可以使用dist(x,method='')
來計算數(shù)據(jù)框或矩陣所有行之間的距離(兩兩樣本之間的距離)
# 營養(yǎng)數(shù)據(jù)集
data(nutrient, package="flexclust")
head(nutrient,5)
distance <- dist(nutrient)
as.matrix(distance)[1:5,1:5] # 使用as.matrix轉為矩陣更容易觀察結果
兩個觀測值之間的距離越大,則其異質性越大
16.3 層次聚類(Hierachical Clustering)
層次聚類算法的原理是根據(jù)樣本之間的距離三娩,每次都把距離最近的兩個樣本合成新的一類庵芭,直到所有樣本都被合成單個類為止。
Hierachical clustering的算法步驟如下
- 定義每個觀測值為一類【即一開始雀监,一個觀測值就是單獨一類】
- 計算每一類和其他各類之間的距離
- 把距離最短的兩類合成一類
- 重復2双吆,3步,直到所有類都合成一個類為止
16.3.1 實現(xiàn)Hierachical Clustering
在R中,Hierachical Clustering可以使用hclust(data,method='')
來實現(xiàn)
nutrient.scaled <- scale(nutrient)
d <- dist(nutrient.scaled)
fit.average <- hclust(d, method="average")
plot(fit.average, hang=-1, cex=.8, main="Hierachical Clustering") # 繪制dendrogram,hang命令展示觀測值的標簽
dendrogram從下網上看伊诵,可以直觀的看出每次迭代后单绑,哪些類被合成了一類
如何看出最優(yōu)的分類個數(shù)呢?NbClust
包提供了NbClust()
方法來確定層次聚類分析的最佳分類個數(shù)曹宴,返回26種方法下推薦的聚類分類個數(shù)
install.packages('NbClust')
library('NbClust')
nc <- NbClust(nutrient.scaled, distance="euclidean",min.nc=2, max.nc=15, method="average")
table(nc$Best.nc[1,]) # 選出不同計算方法下的分類數(shù)目頻數(shù)
barplot(table(nc$Best.nc[1,]),xlab='# of clustering',ylab='# of criteria',main='# of Clusters Chosen by 26 criteria')
使用table(nc$Best.nc[1,])
可以查看26種計算標準下所推薦的不同類別數(shù)量的頻數(shù)分布搂橙,從barplot可以看出,2笛坦、3区转、5、15都可以作為所分的類別數(shù)量
16.3.2 手肘原則
NbClust
包給出的結果下版扩,2废离、3、5礁芦、15 的頻數(shù)相同蜻韭,那么此時我們要用哪個數(shù)作為我們的k呢?這時我們可以使用SSE+手肘原則來選擇最優(yōu)的k
隨著聚類數(shù)k的增大柿扣,樣本劃分會更加精細肖方,每個簇的聚合程度會逐漸提高,那么誤差平方和SSE自然會逐漸變小未状。并且俯画,當k小于真實聚類數(shù)時,由于k的增大會大幅增加每個簇的聚合程度司草,故SSE的下降幅度會很大艰垂,而當k到達真實聚類數(shù)時,再增加k所得到的聚合程度回報會迅速變小埋虹,所以SSE的下降幅度會驟減猜憎,然后隨著k值的繼續(xù)增大而趨于平緩,也就是說SSE和k的關系圖是一個手肘的形狀吨岭,而這個肘部對應的k值就是數(shù)據(jù)的真實聚類數(shù)
library(factoextra)
#設置隨機種子拉宗,保證試驗結果復現(xiàn)
set.seed(123)
#確定最佳聚類個數(shù),使用within sum of square
fviz_nbclust(nutrient.scaled,hcut,method="wss") +geom_vline(xintercept = 5, linetype = 2,color='red')+labs(subtitle = "Elbow method")
# wss stands for within sum of square
當多分一類并不能給模型帶來更好的效果時(SSE下降幅度很欣北琛)旦事,便停止分類。因此根據(jù)上圖的轉折點急灭,可以發(fā)現(xiàn)姐浮,從2-3和4-5都能帶來模型的提升,但是從5-6模型的提升很少葬馋,因此5應該為我們最終使用的k
16.3.2 分類結果的描述
確定了分類次數(shù)k后卖鲤,我們需要使用確定的k再次進行分類(此處k=5
)肾扰,然后對不同類別的特征進行描述
在R中,可以使用cutree(fit,k='')
來對結果按指定的k進行重新分類
然后使用聚合函數(shù)aggregate(data.frame,by=list(),func)
來對結果進行展示蛋逾,并按照聚合函數(shù)結果描述不同類的特征
clusters <- cutree(fit.average,k=5) # 把dendrogram分成5類
table(clusters) # 不同類別中的樣本數(shù)
aggregate(nutrient, by=list(cluster=clusters), median) # 描述不同類
# 重新繪制dendrogram
plot(fit.average, hang=-1, cex=.8, main="5 Cluster Solution") # hang=-1展示標簽
rect.hclust(fit.average, k=5)
Hierachical Clustering的缺點在于集晚,一旦一個樣本值被分配給一個類,那么后續(xù)的迭代中就不能再將它剔除区匣,而劃分聚類分析則可以克服這個缺點
16.4 劃分聚類
劃分聚類算法最常用的算法是k-means算法偷拔,
16.4.1 k-means
K-means算法的基本步驟如下:
-
指定k個質心,一般是算法隨機指定【k為分類數(shù)目】(如圖:cc1和cc2為指定的質心)
- 計算每個樣本點到質心的距離亏钩,每個樣本都被分配到距離其最近的質心所在的類
根據(jù)所計算的距離莲绰,ABC被分配到cc1,DEFG被分配到cc2
-
根據(jù)所在類的所有的樣本值姑丑,重新計算該類的質心的位置【即重新計算cc1和cc2的位置蛤签,cc1 >> cc1' ; cc2>> cc2'】
- 根據(jù)計算出的新質心,重復第2栅哀,3步震肮,直到達到最大迭代次數(shù),或質心位置變化小于指定閾值且各類樣本不在變化
最后ABCE被分配到cc1'所在的類昌屉,DGF被分配到cc2'所在的類
K-means在R語言中
kmeans(data,centers=)
來完成k-means算法钙蒙,data
參數(shù)表示數(shù)據(jù)集,centers
參數(shù)表示要分類的數(shù)目k
根據(jù)業(yè)務或項目要求间驮,如果有明確的分類數(shù)目k,可以直接使用k-means算法马昨;而如果沒有明確的分類數(shù)目k竞帽,一般會使用two-steps clustering,即先使用Hierachical-clustering和SSE找出最優(yōu)分類數(shù)目k后鸿捧,再使用找出的k進行k-means分類
data(wine, package="rattle") # 葡萄酒數(shù)據(jù)
head(wine)
df <- scale(wine[-1]) # standardize
set.seed(1234)
fviz_nbclust(df,kmeans,method="wss") +geom_vline(xintercept = 3, linetype = 2,color='red')+labs(subtitle = "Elbow method")
根據(jù)手肘原則屹篓,k=3為最佳的分類數(shù)目。確定分類數(shù)目后匙奴,使用k_means對指定的k進行分類堆巧,并使用聚合函數(shù)aggregate
對分類結果進行描述
16.4.2 分類結果的描述
set.seed(1234)
fit.kmeans<-kmeans(df,3)
fit.kmeans$size # 查看各類的樣本數(shù)
fit.kmeans$centers # 查看質心的值
aggregate(wine[-1], by=list(cluster=fit.kmeans$cluster), mean) # 聚合函數(shù)描述
# 結果的部分可視化
plot(df[,c('Alcohol','Malic')],col=fit.kmeans$cluster)
points(fit.kmeans$centers[,c('Alcohol','Malic')],col='purple',pch=8)
一般使用聚類算法,都會使用two-step clustering泼菌,由于聚類算法屬于無監(jiān)督學習谍肤,所以并沒有唯一的分類答案,需要根據(jù)具體業(yè)務和項目來靈活應用
參考
[1] Kabacoff, Robert. R 語言實戰(zhàn). Ren min you dian chu ban she, 2016.
[2] https://blog.csdn.net/Anna_datahummingbird/article/details/79912348