如何循环运行K-means聚类?现有R代码故障求助
问题分析与修正方案
看了你的代码,问题主要出在循环中错误地修改原始数据集rd_1,以及没有正确将聚类结果关联到对应的子集上。每次循环你都把results$cluster绑定到全局的rd_1,这会导致rd_1反复新增列,而且聚类结果并没有对应到正确的行;同时你最终的final_data只是拼接了原始子集,没带上聚类标签。
修正后的代码方案
这里提供两种可行的修正思路:
方案1:在子集中添加聚类结果后再合并
这种方式更直观,每次处理一个酒店的子集,生成聚类标签后直接加到子集里,再合并到最终数据:
rd_1 <- mydata ID <- as.character(unique(rd_1$hotel)) final_data <- data.frame() set.seed(65890) # 把随机种子提到循环外,保证结果可复现 for (i in 1:length(ID)) { test_subset <- rd_1[rd_1$hotel == ID[i], ] # 对当前酒店的子集做K-means results <- kmeans(test_subset[, c(3:4)], centers = 3, nstart = 25) # 给当前子集添加聚类结果列 test_subset$cluster <- results$cluster # 合并到最终数据 final_data <- rbind(final_data, test_subset) }
方案2:提前初始化聚类列,循环中赋值
如果你的数据集很大,rbind效率较低,可以先给原始数据加一个空的聚类列,然后循环给每个酒店对应的行赋值:
rd_1 <- mydata ID <- as.character(unique(rd_1$hotel)) # 初始化聚类列 rd_1$cluster <- NA_integer_ set.seed(65890) for (i in 1:length(ID)) { # 找到当前酒店的行索引 row_idx <- which(rd_1$hotel == ID[i]) test_subset <- rd_1[row_idx, c(3:4)] # 运行K-means results <- kmeans(test_subset, centers = 3, nstart = 25) # 给对应行赋值聚类结果 rd_1$cluster[row_idx] <- results$cluster } # 最终结果就在rd_1里,不需要额外合并 final_data <- rd_1
关键改进点
- 把
set.seed()移到循环外,避免每次循环重置种子,保证聚类结果的可复现性。 - 不再修改原始数据集的结构(比如反复新增列),而是将聚类结果精准关联到对应的行/子集。
- 方案2更适合大数据集,避免多次
rbind带来的性能损耗。
内容的提问来源于stack exchange,提问作者Yogesh Kumar




