如何在R中计算FPI和NCE以确定模糊C均值聚类的最优聚类数
R语言e1071包实现模糊C均值聚类最优聚类数选择
基础功能实现
通过自定义FPI、NCE计算函数,遍历不同聚类数拟合模型后可输出双轴可视化结果,完整实现代码如下:
library(e1071) # 1. 数据准备(以iris数据集为例,需先做标准化消除量纲影响) df <- scale(iris[-5]) # 2. 定义模糊性能指数FPI计算函数 FPI <- function(cmem){ c <- ncol(cmem) n <- nrow(cmem) 1 - (c / (c - 1)) * (1 - sum(cmem^2) / n) } # 3. 定义归一化分类熵NCE计算函数 NCE <- function(cmem){ c <- ncol(cmem) n <- nrow(cmem) # 注意此处对数以聚类数c为底,保证结果取值范围为[0,1] (n / (n - c)) * (- sum(cmem * log(cmem, base = c)) / n) } # 4. 遍历聚类数拟合模型,计算指标 max_k <- 6 min_k <- 2 repeat_times <- 10 # 每个聚类数重复运行次数,降低随机初始影响 fpi_mean <- nce_mean <- numeric(max_k - min_k + 1) set.seed(123) # 设置随机种子保证结果可复现 for(i in min_k:max_k){ fpi_tmp <- nce_tmp <- numeric(repeat_times) for(j in 1:repeat_times){ cl <- cmeans(df, centers = i, iter.max = 100, method = "cmeans") fpi_tmp[j] <- FPI(cl$membership) nce_tmp[j] <- NCE(cl$membership) } fpi_mean[i - min_k + 1] <- mean(fpi_tmp) nce_mean[i - min_k + 1] <- mean(nce_tmp) } # 5. 双轴可视化结果 par(mar = c(5,4,1,4) + 0.1) # 绘制FPI曲线 plot(min_k:max_k, fpi_mean, lty = 2, pch = 18, type = "b", xlab = "聚类数", ylab = "FPI", ylim = range(fpi_mean)) # 叠加NCE曲线 par(new = TRUE) plot(min_k:max_k, nce_mean, lty = 1, pch = 15, type = "b", xlab = "", ylab = "", axes = FALSE, ylim = range(nce_mean)) axis(4, at = pretty(range(nce_mean))) mtext("NCE", side = 4, line = 3) # 添加图例 legend("top", legend = c("FPI", "NCE"), pch = c(18,15), lty = c(2,1), horiz = TRUE)
指标单调变化问题解决方案
FPI持续下降、NCE持续上升的问题,核心原因有3点,对应修改方式如下:
- 对数底数错误:标准NCE计算使用以聚类数c为底的对数,而非自然对数,否则结果会随聚类数增大单调上升,修改
log函数的base参数即可解决。 - 未收敛/随机波动:模糊C均值对初始中心敏感,且默认20次迭代可能未收敛,调高
iter.max参数、增加重复运行次数取均值可消除波动,让曲线出现明显拐点。 - 数据聚类结构:如果数据集本身聚类边界极不清晰,也可能出现指标无明显拐点的情况,可先通过轮廓系数、肘部法先验证数据是否适合聚类。
修改后运行代码即可得到存在明显拐点的指标曲线,取FPI和NCE同时最小的聚类数即可作为最优聚类数。
内容的提问来源于stack exchange,提问作者UseR10085
相关产品推荐
相关产品推荐

