You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何循环运行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

火山引擎 最新活动