如何使用fviz_cluster为聚类图添加within-cluster variance标签?
我懂你碰到的麻烦了——用fviz_cluster画聚类图时,想给每个簇加上簇内方差(within-cluster variance)的标签,但直接套geom_label完全没效果,翻官方文档也没找到现成的解决方案对吧?别慌,咱们可以手动计算方差,再把标签精准加到每个簇的中心位置,下面给你一步步演示:
核心思路
fviz_cluster默认用PCA降维展示聚类结果,直接加geom_label会遍历所有样本(而不是簇中心),所以我们需要:
- 计算每个簇的簇内方差
- 拿到每个簇中心在PCA降维空间的坐标
- 把方差文本和坐标整合,再精准添加到图上
示例1:K-Means聚类场景
先从最常用的K-Means开始,代码可直接复用:
# 加载必要的包 library(factoextra) library(dplyr) library(prcomp) # 1. 准备数据和聚类模型 set.seed(123) # 固定随机种子保证结果可复现 data <- scale(iris[,1:4]) # 标准化数据 kmeans_model <- kmeans(data, centers = 3) # 2. 计算簇中心的PCA坐标 + 簇内方差 # 先做PCA(和fviz_cluster默认逻辑一致) pca_result <- prcomp(data, scale. = FALSE) # 把簇中心映射到PCA空间,同时计算平均簇内方差(总平方和/样本数) cluster_labels <- predict(pca_result, newdata = kmeans_model$centers) %>% as.data.frame() %>% mutate( cluster = factor(1:nrow(.)), within_var = kmeans_model$withinss / kmeans_model$size, label_text = paste("Within Var:", round(within_var, 2)) # 格式化标签文本 ) # 3. 画图并添加标签 # 先画基础聚类图 base_plot <- fviz_cluster( kmeans_model, data = data, geom = "point", ellipse.type = "convex", ggtheme = theme_minimal() ) # 给每个簇中心加方差标签 base_plot + geom_label( data = cluster_labels, aes(x = PC1, y = PC2, label = label_text), color = "darkred", fontface = "bold", size = 4 )
示例2:层次聚类场景
如果用的是层次聚类,只需要调整簇中心和方差的计算逻辑:
# 1. 构建层次聚类模型 hc_model <- hclust(dist(data), method = "ward.D2") clusters <- cutree(hc_model, k = 3) # 分成3个簇 # 2. 计算簇中心、方差和PCA坐标 cluster_stats <- data %>% as.data.frame() %>% mutate(cluster = factor(clusters)) %>% group_by(cluster) %>% summarise( across(everything(), mean), # 计算簇中心 size = n(), within_ss = sum(rowSums((cur_data()[,1:4] - cur_data()[,1:4])^2)) # 簇内总平方和 ) %>% mutate( within_var = within_ss / size, label_text = paste("Within Var:", round(within_var, 2)) ) # 映射簇中心到PCA空间 cluster_labels_hc <- predict(pca_result, newdata = cluster_stats[,1:4]) %>% as.data.frame() %>% mutate( cluster = cluster_stats$cluster, label_text = cluster_stats$label_text ) # 3. 画图加标签 base_plot_hc <- fviz_cluster( list(data = data, cluster = clusters), geom = "point", ellipse.type = "convex", ggtheme = theme_minimal() ) base_plot_hc + geom_label( data = cluster_labels_hc, aes(x = PC1, y = PC2, label = label_text), color = "darkblue", fontface = "bold", size = 4 )
关键说明
- 簇内方差我用了平均平方距离(总平方和/簇内样本数),如果你想展示总平方和,直接用
kmeans_model$withinss或者层次聚类里的within_ss就行 - 标签的位置、颜色、大小都可以通过
geom_label的参数调整,比如加nudge_x/nudge_y可以让标签避开簇中心点
内容的提问来源于stack exchange,提问作者user9343592
相关产品推荐
相关产品推荐

