R语言聚类分析:无ground truth时相关系数阈值最优聚类选择
无ground truth下的阈值聚类最优方案说明
你当前的聚类逻辑是基于样本间皮尔逊相关系数绝对值的阈值构造邻接图,取连通分量作为聚类结果。你之前考虑的adjusted R2属于需要真实标签作为参考的外部评估指标,没有ground truth时确实无法计算,换用内部聚类有效性指标即可完成阈值筛选,具体操作如下:
1. 封装阈值遍历的聚类函数
先将你现有代码封装为可传入阈值、返回聚类标签的通用函数,方便批量跑不同阈值的结果:
get_cluster_by_threshold <- function(df, threshold) { cor_mat <- abs(cor(t(df))) g <- graph_from_adjacency_matrix(cor_mat > threshold) comp <- components(g) return(as.vector(comp$membership)) }
2. 选择适配的内部评估指标
推荐三类适合你这类图连通聚类的无监督评估指标:
- 轮廓系数(Silhouette Coefficient):衡量每个样本与自身所在簇其他样本的平均紧密程度,以及与最近邻其他簇样本的分离程度,取值范围[-1,1],整体均值越接近1说明聚类效果越好。
- 戴维斯-布尔丁指数(Davies-Bouldin Index):计算簇间相似度与簇内相似度的比值,取值越小说明聚类区分度越高、簇内聚合性越好。
- 连通性(Connectivity):图聚类专属指标,衡量空间相邻的样本是否被划分到同一个簇的匹配程度,取值越小说明聚类越符合原始样本的邻接关系。
3. 遍历阈值计算指标
以下是批量计算不同阈值对应评估结果的示例代码,你可以根据需求调整阈值的测试范围和步长:
library(cluster) # 定义测试阈值范围,可自行调整 threshold_list <- seq(0.5, 0.95, by = 0.05) # 初始化结果存储表 eval_res <- data.frame( threshold = threshold_list, silhouette = NA, db_index = NA, cluster_num = NA ) # 提前计算样本距离矩阵复用,减少重复计算耗时 sample_dist <- dist(df) for (i in seq_along(threshold_list)) { current_th <- threshold_list[i] clust_labels <- get_cluster_by_threshold(df, current_th) # 跳过聚类数不足2、或单簇占比过高的无效阈值 if (length(unique(clust_labels)) < 2 | max(table(clust_labels))/nrow(df) > 0.95) { next } # 记录聚类数量 eval_res$cluster_num[i] <- length(unique(clust_labels)) # 计算轮廓系数均值 sil_res <- silhouette(clust_labels, sample_dist) eval_res$silhouette[i] <- mean(sil_res[,3]) # 计算戴维斯-布尔丁指数 eval_res$db_index[i] <- davies.bouldin(sample_dist, clust_labels)$DB }
4. 最优阈值选择
优先选择轮廓系数最大、戴维斯-布尔丁指数最小的阈值即可。如果多个阈值的评估指标接近,也可以结合你对聚类数量的业务需求做折中选择。
注意事项
- 如果高阈值下出现大量单样本簇,说明阈值设置过于严格,可以适当降低阈值上限再测试。
- 如果数据存在明显噪声,可提前过滤方差极低的无效样本后再做评估,避免噪声干扰指标计算结果。
内容的提问来源于stack exchange,提问作者ncnc_2020
相关产品推荐
相关产品推荐

