基于cluster::clara的k-medoids多区域分类标签对齐方法咨询
多区域k-medoids聚类标签对齐方案
出现标签翻转的核心原因是聚类输出的标签仅为簇的序号,无实际语义,不同样本集独立聚类时序号分配规则不固定,二分类场景下极易出现标签反转的情况。你可以采用基准锚定映射法解决该问题,无需合并全量数据,内存开销和原有实现基本一致,适配9万级区域的处理需求。
具体实现逻辑
- 先选取第一个区域(或任意代表性区域)的聚类中心点作为全局基准,记录两个中心点对应的标签映射关系
- 后续每个区域独立完成clara聚类后,计算当前区域的两个中心点与基准中心点的匹配度,按距离最近原则对齐标签:如果当前簇1更接近基准簇2、当前簇2更接近基准簇1,则翻转当前区域的所有标签
- 最终输出的所有区域标签语义完全一致
修改后的代码示例
# Packages library(cluster) library(ggplot2) my_ds <-read.csv("https://raw.githubusercontent.com/Leprechault/trash/main/class_areas_ds.csv") # Classification based in `R` and `HUE` variables res<-NULL areas<-unique(my_ds$ID) base_meds <- NULL # 存储基准中心点 for(i in 1:length(areas)){ my_ds_split<-my_ds[my_ds$ID==areas[i],] k.medoids.res<-cluster::clara(my_ds_split[,4:ncol(my_ds_split)], 2, metric ="manhattan") current_meds <- k.medoids.res$medoids current_class <- k.medoids.res$clustering # 第一个区域作为基准,保存中心点 if(i == 1){ base_meds <- current_meds } else { # 计算两种匹配的总曼哈顿距离 match_normal <- sum(abs(current_meds[1,] - base_meds[1,])) + sum(abs(current_meds[2,] - base_meds[2,])) match_reverse <- sum(abs(current_meds[1,] - base_meds[2,])) + sum(abs(current_meds[2,] - base_meds[1,])) # 反向匹配更优则翻转标签 if(match_reverse < match_normal){ current_class <- ifelse(current_class == 1, 2, 1) } } # 转换为0/1标签,和原逻辑对齐 current_class <- ifelse(current_class ==1, 0, 1) my_ds_split.F<-cbind(my_ds_split, class = current_class) res<-rbind(res, my_ds_split.F) } res<-as.data.frame(res) # 后续绘图逻辑不变,输出的两个区域标签已对齐
可选优化方案
如果你的聚类特征有明确的业务语义,比如已知高R值对应类别0、低R值对应类别1,可以直接按业务规则重映射标签,无需依赖基准区域:
# 每个区域聚类后,按簇的R值均值排序映射标签 mean_r_by_class <- tapply(my_ds_split$R, current_class, mean) class_map <- setNames(c(0,1), names(sort(mean_r_by_class, decreasing = TRUE))) # 高R为0,低R为1 current_class <- class_map[as.character(current_class)]
内容的提问来源于stack exchange,提问作者Leprechault
相关产品推荐
相关产品推荐

