基于R语言kmeans算法评估3D表面点的空间聚类性
检测3D表面点的聚类性:用R的K-Means找最优簇数
嘿,针对你用R判断3D表面点是随机分布还是存在聚类的需求,我整理了一套实用的步骤,尤其是用K-Means找最优簇数的部分,刚好能覆盖你说的多指标测试需求~
第一步:先给数据做个小预处理
首先得确保你的df里的x、y、z坐标都是数值型,先检查下:
str(df) # 提取坐标列(假设列名就是x、y、z) points_3d <- df[, c("x", "y", "z")]
如果有缺失值的话,记得先清理掉,不然会影响后续计算:
points_3d <- na.omit(points_3d)
第二步:用多指标确定最优簇数
你提到要测试30种指标,刚好R里的NbClust包集成了绝大多数常用的聚类评估指标,能一次性帮你搞定;另外也可以配合可视化方法,更直观地判断最优k值。
先装好用得上的包
# 没装过的话先安装 install.packages(c("factoextra", "NbClust", "rgl")) library(factoextra) library(NbClust) library(rgl)
方法1:用NbClust一次性跑遍多指标
这个包会自动测试你指定范围内的簇数,然后基于30种左右的指标给出最优k的建议,非常省心:
# 运行NbClust,设置簇数范围(比如2到10,可根据你的数据调整) nb_result <- NbClust(data = points_3d, distance = "euclidean", # 3D点用欧氏距离很合适 min.nc = 2, max.nc = 10, method = "kmeans", index = "all") # 启用所有可用指标 # 查看最优簇数的汇总结果 nb_result$Best.nc
结果里会显示各个指标推荐的k值,你可以取出现次数最多的那个作为参考。
方法2:可视化关键指标(更直观)
除了批量跑指标,单独看几个核心指标的变化也很有用,比如肘部法和轮廓系数:
肘部法(找拐点)
看总簇内平方和(WSS)随k增加的变化,当WSS下降速度突然变慢的那个点,就是最优k:
# 计算不同k对应的WSS wss_values <- sapply(1:10, function(k){ kmeans(points_3d, k, nstart=20)$tot.withinss }) # 绘图并标记拐点 plot(1:10, wss_values, type="b", pch=19, xlab="Number of clusters (k)", ylab="Total within-clusters sum of squares") abline(v = which.min(diff(diff(wss_values))), col="red", lty=2)
轮廓系数(看簇的紧密性)
这个指标衡量簇内点的紧密程度和簇间的分离程度,系数越高,聚类效果越好:
# 计算不同k对应的平均轮廓系数 sil_values <- sapply(2:10, function(k){ km_model <- kmeans(points_3d, k, nstart=20) silhouette(km_model$cluster, dist(points_3d))$avg.width }) # 绘图并标记最优k plot(2:10, sil_values, type="b", pch=19, xlab="Number of clusters (k)", ylab="Average Silhouette Width") abline(v = which.max(sil_values)+1, col="red", lty=2)
第三步:验证聚类是不是真的“非随机”
当你确定了最优k之后,还可以做两步验证:
- 3D可视化看效果:把聚类后的点在3D空间里画出来,直观判断是不是有明显的簇:
# 用最优k值跑最终的kmeans模型 final_km <- kmeans(points_3d, k=你的最优k值, nstart=20) # 3D绘图,不同簇用不同颜色 plot3d(points_3d$x, points_3d$y, points_3d$z, col=final_km$cluster, size=2, xlab="X", ylab="Y", zlab="Z")
如果能看到明显的颜色聚集,那大概率存在聚类。
- 置换检验验证显著性:把点的坐标随机打乱,重新跑kmeans,对比真实数据和随机数据的WSS。如果真实数据的WSS远低于随机数据,说明聚类不是随机产生的,是真实存在的。
小提醒
因为你的点是在3D表面上,如果表面形状很复杂(比如有褶皱、孔洞),欧氏距离可能不能准确反映点在表面上的实际距离。这种情况下,你可以考虑先把3D点映射到2D参数空间(比如用主成分分析PCA降维),再做聚类,结果会更准确。
内容的提问来源于stack exchange,提问作者Andrea Paterlini
相关产品推荐
相关产品推荐

