如何在同一绘图框中展示健康与故障数据集的MClust GMM聚类结果
没问题!我来帮你实现健康和故障数据GMM聚类结果的同图对比,不管是密度曲线还是聚类散点/椭圆都能搞定,下面分步骤给你具体方案:
核心思路
要把两组数据的聚类结果放在同一图里,关键是分别提取两组聚类的核心参数(比如密度估计、聚类中心、协方差矩阵),然后用基础绘图或ggplot手动合并可视化元素——毕竟MClust自带的plot()函数默认是单独绘图,没法直接合并。
步骤1:先确保两组数据的聚类结果都已保存
首先你已经分别跑了MClust,先把结果存成不同的对象,方便后续调用:
library(mclust) # 假设你的健康数据集是health_data,故障数据集是fault_data health_clust <- Mclust(health_data, G = 3) fault_clust <- Mclust(fault_data, G = 3)
方案1:密度曲线对比(重点展示故障数据的两个混合成分)
如果你的需求是对比两组数据的混合密度曲线,同时单独标出故障数据里CCD和CCA对应的两个成分密度,可以这样做:
# 选择你要可视化的变量(比如第1个变量,替换成你需要的列索引) var_idx <- 1 # 生成覆盖两组数据范围的x轴序列 x_range <- range(c(health_data[, var_idx], fault_data[, var_idx])) x_seq <- seq(x_range[1], x_range[2], length.out = 1000) # 计算健康数据的整体混合密度 health_dens <- predict(health_clust, newdata = data.frame(x = x_seq), what = "density") # 计算故障数据的整体混合密度 fault_dens <- predict(fault_clust, newdata = data.frame(x = x_seq), what = "density") # 提取故障数据中目标成分的密度(先确认哪两个是CCD/CCA,比如假设是成分1和2) # 成分密度 = 权重 × 单高斯密度 fault_comp1_dens <- fault_clust$parameters$pro[1] * dnorm(x_seq, mean = fault_clust$parameters$mean[var_idx], sd = sqrt(fault_clust$parameters$variance$sigmasq[var_idx])) fault_comp2_dens <- fault_clust$parameters$pro[2] * dnorm(x_seq, mean = fault_clust$parameters$mean[var_idx], sd = sqrt(fault_clust$parameters$variance$sigmasq[var_idx])) # 开始绘图 plot(x_seq, health_dens, type = "l", col = "#1f77b4", lwd = 2, xlab = paste0("Variable ", var_idx), ylab = "Density", main = "Healthy vs Fault Data: GMM Density Comparison") # 添加故障数据整体密度 lines(x_seq, fault_dens, col = "#ff4b5c", lwd = 2) # 添加故障数据的两个目标成分密度(用虚线区分) lines(x_seq, fault_comp1_dens, col = "#ff4b5c", lty = 2, lwd = 1.5) lines(x_seq, fault_comp2_dens, col = "#ff4b5c", lty = 3, lwd = 1.5) # 添加图例,清晰区分各元素 legend("topright", legend = c("Healthy (GMM)", "Fault (GMM)", "Fault - CCD", "Fault - CCA"), col = c("#1f77b4", "#ff4b5c", "#ff4b5c", "#ff4b5c"), lty = c(1,1,2,3), lwd = c(2,2,1.5,1.5), bty = "n")
方案2:散点图+聚类椭圆对比(展示空间分布)
如果要对比两组数据的聚类空间分布(比如前两个变量的散点+聚类椭圆),可以用ggplot结合ggforce包来画:
library(ggplot2) library(ggforce) # 合并两组数据,添加组别和聚类标签 combined_df <- rbind( cbind(health_data, group = "Healthy", cluster = as.factor(health_clust$classification)), cbind(fault_data, group = "Fault", cluster = as.factor(fault_clust$classification)) ) # 提取聚类椭圆的参数(以前两个变量为例) get_ellipse_params <- function(clust_result, group_name) { lapply(1:3, function(k) { cov_mat <- clust_result$parameters$variance$sigma[,,k] data.frame( group = group_name, cluster = as.factor(k), mean_x = clust_result$parameters$mean[1], mean_y = clust_result$parameters$mean[2], # 计算椭圆的长半轴、短半轴和旋转角度(2倍标准差覆盖大部分数据) a = sqrt(cov_mat[1,1]) * 2, b = sqrt(cov_mat[2,2]) * 2, angle = atan2(cov_mat[1,2], cov_mat[1,1]) * (180/pi) ) }) %>% do.call(rbind, .) } health_ellipses <- get_ellipse_params(health_clust, "Healthy") fault_ellipses <- get_ellipse_params(fault_clust, "Fault") all_ellipses <- rbind(health_ellipses, fault_ellipses) # 绘制可视化图 ggplot(combined_df, aes(x = V1, y = V2)) + geom_point(aes(color = group, shape = cluster), alpha = 0.6, size = 1.5) + # 添加聚类椭圆 geom_ellipse(data = all_ellipses, aes(x0 = mean_x, y0 = mean_y, a = a, b = b, angle = angle, color = group), fill = NA, lwd = 1.2) + labs(title = "Clustering Distribution: Healthy vs Fault Data", x = "Variable 1", y = "Variable 2") + theme_minimal() + scale_color_manual(values = c("Healthy" = "#1f77b4", "Fault" = "#ff4b5c"))
小提示
- 如果你不确定故障数据里哪两个成分对应CCD和CCA,可以通过
fault_clust$parameters$mean查看各成分的均值,结合业务知识判断;也可以用plot(fault_clust, what = "classification")先单独看故障数据的聚类分类,确认目标成分的编号。 - 如果要可视化4个变量的成对对比,可以用
pairs()函数手动叠加两组数据的聚类标记和密度曲线,不过操作会复杂一些,上面的方案是最常用的单变量/双变量可视化方式。
内容的提问来源于stack exchange,提问作者sumitpal0593
相关产品推荐
相关产品推荐

