聚類分析是一種常用的無監督學習方法,是將所觀測的事物或者指標進行分類的一種統計分析方法,其目的是通過辨認在某些特征上相似的事物,并將它們分成各種類別。R語言提供了多種聚類分析的方法和包。
方法 | 優點 | 缺點 | 適用場景 |
---|---|---|---|
K-means | 計算效率高 | 需預設K值 | 球形數據分布 |
層次聚類 | 可視化直觀 | 計算復雜度O(n2) | 小數據集/層級關系分析 |
DBSCAN | 發現任意形狀 | 參數敏感 | 噪聲數據/密度差異大 |
PAM | 對異常值魯棒 | 計算成本高 | 中小規模數據 |
一、層次聚類
它是通過計算樣本之間的距離來構建一個層次化的聚類結構,結果通常用樹狀圖(dendrogram)來表示。
實現層次聚類的常用函數是R語言內置函數hclust(),還可以用cluter擴展包的agens()函數和flashClust擴展包的hclust()函數。
1、hclust()函數
下面用flexclust擴展包中的milk數據集進行講解,此數據集包含了25種哺乳動物乳汁的成分數據:水分(water)、蛋白質(protein)、乳糖(lactose)、脂肪(fat)和灰分(ash)。
1.1 準備數據
library(flexclust)
# 第1步 準備數據:查看數據
data(milk)
milk
?
1.2 標準化數據?
# 第2步 標準化數據
milk_data <- scale(milk, center=T, scale=T)
milk_data
1.3 計算距離
# 第3步 計算歐幾里得距離;也可以選用其它方法
milk_dist <- dist(milk_data, method="euclidean")
milk_dist
1.4 層次聚類
?使用平均距離法進行層次聚類
# 使用平均距離法進行層次聚類
fit_average <- hclust(milk_dist, method="averge")
fit_average
使用離差平和法進行層次聚類
# 使用平均距離法進行層次聚類
fit_average <- hclust(milk_dist, method="ward.D2")
fit_average
1.5 可視化結果
plot(fit_average, hang=-1, cex=1.2,main="平均距離層次聚類")
plot(fit_average, hang = -1, main = "層次聚類樹狀圖", xlab = "樣本", sub = "")
# 用矩形標出3個聚類
rect.hclust(fit_average, k = 3, border = 2:4)
?1.6 切割聚類并評估
使用flexclust擴展包中的cuttree()函數將聚類結果分為3類(為什么分為3類,在此不細究,可上網查詢方法)。
clusters <- cutree(fit_average, k=3)
# 可視化結果
plot(fit_average, hang=-1, cex=1, main="平均距離層次最終聚類")
rect.hclust(fit_average, k=3)
二、K-均值聚類?
1、kmeans()函數
層次聚類是一次性的,即樣本點一旦被劃分道一個類中,就不會再被分配到其它的類中,而且當樣本量達到數百甚至數千時,層次聚類會很難處理。
R語言中最常用的K-均值聚類函數時kmeans()函數。
1.1 數據準備
用R語言內置的iris數據集為例。首先需要將類別信息去除。
head(iris)
iris_data <- iris[, 1:4]
head(iris_data)
1.2 標準化數據
# 標準化數據,消除量綱的影響
iris_scaled <- scale(iris_data, center=T, scale=TRUE)
head(iris_scaled)
?1.3 選擇最佳K值
使用肘部法選擇最佳的K值:通過計算不同聚類數k對應的總組內平方和(Total Within-Cluster Sum of Squares, WSS),找到WSS下降速度顯著變緩的“肘部”點,該點對應的k即為最佳聚類數。
wss <- numeric(10)
for (k in 1:10) {kmeans_model <- kmeans(iris_scaled, centers = k, nstart = 25)wss[k] <- kmeans_model$tot.withinss
}
plot(1:10, wss, type = "b", pch = 19, main = "肘部法選擇最佳k值", xlab = "聚類數k", ylab = "總組內平方和(WSS)")
從下面的截圖可知,當k=3時,下降速度明顯變緩。?
?1.4 K-均值聚類
centers:聚類數k。
nstart:隨機初始中心點的次數(建議設為25以減少局部最優影響)。
iter.max:最大迭代次數(默認10)。
set.seed(123)
# 進行K-均值聚類
fit_means <- kmeans(iris_scaled, centers=3, iter.max=100, nstart=25)
1.5 可視化結果
library(factoextra)
fviz_cluster(fit_means, data = iris_scaled, palette = "jco", # 配色方案geom = "point", # 僅顯示點ellipse.type = "norm", # 添加正態分布橢圓ggtheme = theme_minimal())
?