如何在R中实现SPSS式自动选聚类数的两步聚类分析
在R中实现SPSS风格的两步聚类分析
SPSS的两步聚类核心是先自动筛选最优聚类数,再用k-means完成聚类。你用的prcr::create_profiles_cluster需要手动指定聚类数,确实不符合需求,下面是可行的实现方案,基于你的iris数据集示例:
第一步:自动确定最优聚类数
我们可以结合肘部法则、轮廓系数或Gap统计量来自动判断最优聚类数,这里以肘部法则+轮廓系数的组合为例(兼顾直观性和统计合理性):
首先加载所需包:
library(cluster) library(factoextra) # 辅助可视化肘部法则
然后对数据做预处理(和你原来的步骤一致):
# 数据预处理:去除缺失值、标准化特征 daten.iris <- na.omit(iris) daten.iris_scaled <- scale(daten.iris[, -5])
方法1:肘部法则
计算不同k值下的总平方和(WSS),找到曲线的拐点:
# 计算1到10类的WSS wss <- sapply(1:10, function(k) { kmeans(daten.iris_scaled, centers = k, nstart = 25)$tot.withinss }) # 可视化肘部曲线 plot(1:10, wss, type = "b", pch = 19, frame = FALSE, xlab = "聚类数 k", ylab = "总类内平方和(WSS)") abline(v = 3, lty = 2, col = "red") # 示例中拐点在k=3
方法2:轮廓系数
计算不同k值的平均轮廓系数,取系数最大的k:
# 计算2到10类的平均轮廓系数 sil_avg <- sapply(2:10, function(k) { km <- kmeans(daten.iris_scaled, centers = k, nstart = 25) sil <- silhouette(km$cluster, dist(daten.iris_scaled)) mean(sil[, 3]) }) # 找到最优k optimal_k <- which.max(sil_avg) + 1 # 因为我们从k=2开始计算 cat("最优聚类数:", optimal_k, "\n")
方法3:Gap统计量
通过比较实际聚类的WSS和随机数据的WSS差异确定最优k:
set.seed(123) # 保证结果可复现 gap_stat <- clusGap(daten.iris_scaled, FUN = kmeans, nstart = 25, K.max = 10, B = 50) # B是随机数据的重复次数 # 可视化Gap统计量 fviz_gap_stat(gap_stat) optimal_k_gap <- which.max(gap_stat$Tab[, "gap"]) cat("Gap统计量推荐的最优聚类数:", optimal_k_gap, "\n")
通常三种方法结果会一致(比如iris数据集最优k都是3),你可以根据自己的数据选择最适合的方法。
第二步:用k-means执行聚类
拿到最优聚类数后,直接调用基础包的kmeans函数完成聚类:
# 使用轮廓系数得到的最优k set.seed(123) km_result <- kmeans(daten.iris_scaled, centers = optimal_k, nstart = 25) # 将聚类结果合并到原数据 daten.iris$cluster <- km_result$cluster # 查看聚类结果 table(daten.iris$cluster, daten.iris$Species) # 对比真实标签和聚类结果
补充说明
nstart = 25是为了避免k-means陷入局部最优,建议设置较大的nstart值;- 如果你的数据包含分类变量,SPSS的两步聚类支持混合类型,但上面的方法仅针对数值型数据。如果需要处理混合类型,可以使用
flexclust包的kcca函数,结合合适的距离度量(比如Gower距离); - 如果你想更贴近SPSS两步聚类的逻辑(先预聚类再优化),也可以先用
hclust做层次聚类预分组,再用k-means细化,但通常直接用上述方法确定k后做k-means就足够。
内容的提问来源于stack exchange,提问作者manofthousandnames
相关产品推荐
相关产品推荐

