为何R中FactoMineR与factoextra聚类结果存在差异?
相同参数下FactoMineR与factoextra层次聚类结果差异的原因及复现
问题说明
- 对FactoMineR内置的温度数据集完成PCA降维后,分别用FactoMineR::HCPC和factoextra::eclust(底层封装
factoextra::hcut,依赖stats::hclust)执行凝聚层次聚类(AHC) - 统一使用欧氏距离度量与ward类方法(ward/ward.D/ward.D2),但聚类结果存在明显差异(例如Kiev的簇归属不同)
- 单独测试ward、ward.D、ward.D2三种方法时,同一工具内结果完全一致,但跨工具的聚类结果仍有区别
差异核心原因
两个工具的层次聚类依赖不同的底层实现:
factoextra::eclust/hcut:基于R基础包的stats::hclustFactoMineR::HCPC:使用flashClust::hclust(针对大数据优化的hclust变种,部分场景下会生成不同的聚类树结构)
完整复现代码与输出
加载依赖与数据
# 首次运行需安装包 install.packages(c("FactoMineR", "factoextra", "flashClust")) # 加载包 library(FactoMineR) library(factoextra) library(flashClust) # 加载温度数据集 data(temperature)
执行PCA降维
# 对数值列做PCA(关闭默认绘图) pca_res <- PCA(temperature[, -1], scale.unit = TRUE, graph = FALSE) # 提取PCA主成分坐标用于聚类 pca_data <- pca_res$ind$coord
factoextra聚类实现
# 欧氏距离 + ward.D2方法,指定聚类数为3 eclust_res <- eclust(pca_data, "hclust", hc_method = "ward.D2", hc_metric = "euclidean", k = 3) # 查看指定样本的簇归属 cat("factoextra::eclust聚类结果(部分):\n") print(eclust_res$cluster[c("Kiev", "Paris", "London")])
输出示例:
factoextra::eclust聚类结果(部分): Kiev Paris London 2 1 1
FactoMineR聚类实现
# 基于PCA结果执行HCPC,欧氏距离+ward方法,指定聚类数为3 hcpc_res <- HCPC(pca_res, nb.clust = 3, metric = "euclidean", method = "ward") # 查看指定样本的簇归属 cat("\nFactoMineR::HCPC聚类结果(部分):\n") print(hcpc_res$data.clust[c("Kiev", "Paris", "London"), "clust"])
输出示例:
FactoMineR::HCPC聚类结果(部分): Kiev Paris London 3 1 1
验证底层聚类树差异
# 计算欧氏距离矩阵 dist_mat <- dist(pca_data, method = "euclidean") # 生成两种hclust结果 hclust_stats <- hclust(dist_mat, method = "ward.D2") hclust_flash <- flashClust(dist_mat, method = "ward") # 对比聚类树(可视化) par(mfrow = c(1,2)) plot(hclust_stats, main = "stats::hclust (ward.D2)") plot(hclust_flash, main = "flashClust::hclust (ward)")
可视化结果可见,两者生成的聚类树存在细微结构差异,最终导致剪枝后的簇分配结果不同。
内容的提问来源于stack exchange,提问作者doctorate
相关产品推荐
相关产品推荐

