news 2026/6/13 3:54:53

R语言PCA可视化:用ggplot2给鸢尾花数据加置信椭圆(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
R语言PCA可视化:用ggplot2给鸢尾花数据加置信椭圆(附完整代码)

R语言PCA可视化实战:用ggplot2为鸢尾花数据绘制精美置信椭圆

鸢尾花数据集作为统计学和机器学习领域的经典案例,常被用于演示分类算法和降维技术。主成分分析(PCA)能有效提取数据关键特征,而置信椭圆则直观展示不同类别数据的分布范围。本文将手把手教你如何用R语言的ggplot2包,为鸢尾花PCA结果添加专业级置信椭圆。

1. 环境准备与数据加载

在开始之前,确保已安装必要的R包。如果尚未安装,可以通过以下命令获取:

install.packages(c("ggplot2", "dplyr"))

加载所需库并查看数据概览:

library(ggplot2) library(dplyr) head(iris)

鸢尾花数据集包含150个样本,每个样本有4个特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度)和1个分类标签(setosa、versicolor、virginica)。我们将使用前4个数值型变量进行PCA分析。

2. 主成分分析实现

R语言提供了多个PCA函数,最常用的是prcomp()princomp()。两者计算原理相似,但输出格式略有不同。这里我们使用prcomp()

# 执行PCA分析 pca_result <- prcomp(iris[, 1:4], scale. = TRUE) # 查看PCA结果摘要 summary(pca_result)

提示:scale.=TRUE参数会对数据进行标准化处理,消除不同特征量纲的影响,这在变量单位不一致时尤为重要。

PCA结果中,sdev表示各主成分的标准差,rotation是特征向量(载荷矩阵),x则是转换后的主成分得分。我们可以提取前两个主成分用于可视化:

# 创建包含主成分得分和原始分类的数据框 pca_data <- data.frame( PC1 = pca_result$x[, 1], PC2 = pca_result$x[, 2], Species = iris$Species )

3. 基础PCA可视化

在添加置信椭圆前,先绘制基本的PCA散点图:

# 计算各主成分的方差贡献率 var_exp <- pca_result$sdev^2 / sum(pca_result$sdev^2) ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + geom_point(size = 3) + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)"), title = "鸢尾花数据集PCA分析" ) + theme_minimal()

这段代码会生成一个彩色散点图,不同颜色的点代表不同鸢尾花品种。x轴和y轴标签自动包含了各主成分解释的方差百分比。

4. 置信椭圆绘制详解

ggplot2的stat_ellipse()函数可以方便地添加置信椭圆。该函数有几个关键参数需要理解:

  • type:指定椭圆计算的统计假设

    • "norm":基于多元正态分布(默认)
    • "t":基于多元t分布(更保守)
  • level:置信水平,默认为0.95(即95%置信区间)

  • geom:指定椭圆的表现形式

    • "path":仅绘制椭圆轮廓
    • "polygon":填充椭圆区域

4.1 基本置信椭圆实现

为每个品种添加95%置信椭圆(填充效果):

ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + stat_ellipse( aes(fill = Species), type = "norm", geom = "polygon", alpha = 0.2, level = 0.95 ) + geom_point(size = 3) + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)") ) + theme_minimal()

4.2 椭圆样式自定义

通过调整参数,可以创建不同风格的置信椭圆:

ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + stat_ellipse( aes(fill = Species), type = "t", # 使用t分布假设 geom = "polygon", alpha = 0.1, level = 0.99, # 99%置信区间 linetype = 2, # 虚线边框 size = 0.5 # 边框线粗细 ) + geom_point(size = 3, alpha = 0.8) + scale_fill_brewer(palette = "Set1") + scale_color_brewer(palette = "Set1") + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)"), title = "鸢尾花PCA分析(99%置信区间)" ) + theme_bw()

5. 高级美化技巧

5.1 分面显示

当类别较多或重叠严重时,可以使用分面(facet)功能:

ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + stat_ellipse( aes(fill = Species), type = "norm", geom = "polygon", alpha = 0.2 ) + geom_point(size = 2) + facet_wrap(~Species) + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)") ) + theme_minimal() + theme(legend.position = "none") # 移除图例

5.2 添加密度等高线

结合geom_density_2d()可以进一步增强可视化效果:

ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + stat_ellipse( aes(fill = Species), type = "norm", geom = "polygon", alpha = 0.1 ) + geom_density_2d(alpha = 0.5, size = 0.5) + geom_point(size = 2, alpha = 0.7) + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)") ) + theme_minimal()

5.3 保存高质量图片

使用ggsave()保存适合发表的图片:

final_plot <- ggplot(pca_data, aes(x = PC1, y = PC2, color = Species)) + stat_ellipse( aes(fill = Species), type = "norm", geom = "polygon", alpha = 0.2 ) + geom_point(size = 3) + labs( x = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), y = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)") ) + theme_minimal() ggsave("iris_pca_ellipse.png", final_plot, width = 8, height = 6, dpi = 300)

6. 实际应用中的注意事项

  1. 数据标准化:PCA对变量的尺度敏感,确保使用scale.=TRUE或提前标准化数据

  2. 置信水平选择

    • 科研论文常用95%置信水平
    • 更严格的场景可使用99%
    • 探索性分析可降低至90%
  3. 分布假设选择

    • 数据接近正态分布时使用type="norm"
    • 存在离群值时考虑type="t"
  4. 类别重叠解读

    • 椭圆重叠度高表明类别区分度低
    • 完全分离的椭圆表示类别特征差异明显
  5. 高维数据扩展

    • 对于更高维数据,可考虑绘制PC1-PC3等组合
    • 使用3D散点图展示多主成分关系
# 示例:3D PCA绘图(需要rgl包) library(rgl) plot3d( x = pca_data$PC1, y = pca_data$PC2, z = pca_result$x[, 3], col = as.numeric(pca_data$Species), size = 5, xlab = paste0("PC1 (", round(var_exp[1] * 100, 1), "%)"), ylab = paste0("PC2 (", round(var_exp[2] * 100, 1), "%)"), zlab = paste0("PC3 (", round(var_exp[3] * 100, 1), "%)") ) legend3d("topright", legend = levels(pca_data$Species), pch = 16, col = 1:3, cex = 1)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 3:52:21

别再只会抄经典电路了!手把手教你用MAX485芯片设计一个带自动收发切换的TTL转RS485模块

从零构建高可靠MAX485自动收发电路&#xff1a;工程师的实战避坑指南当你的单片机需要与百米外的传感器对话时&#xff0c;那些在面包板上运行良好的TTL电平突然变得脆弱不堪。我曾亲眼目睹一个工业现场因为RS485收发切换延迟导致整条生产线停摆——原因仅仅是设计者直接照搬了…

作者头像 李华