基于PCA绘制species与predicted_species矩阵9张子图Biplot的方案咨询
高效实现原生与预测物种组合的PCA Biplot子图网格
问题背景
给定如下数据集片段:
species bill_length_mm bill_depth_mm flipper_length_mm body_mass_g predicted_species 0 Adelie 18 18 181 3750 Chinstrap 1 Adelie 17 17 186 3800 Adelie 2 Adelie 18 18 195 3250 Gentoo 3 Adelie 0 0 0 0 Adelie 4 Chinstrap 19 19 193 3450 Chinstrap 5 Chinstrap 20 20 190 3650 Gentoo 6 Chinstrap 17 17 181 3625 Adelie 7 Gentoo 19 19 195 4675 Chinstrap 8 Gentoo 18 18 193 3475 Gentoo 9 Gentoo 20 20 190 4250 Gentoo
需求:基于数值特征(bill_length_mm、bill_depth_mm、flipper_length_mm、body_mass_g)执行PCA降维,绘制类似Biplot的可视化图,同时生成原生species与预测predicted_species所有9种组合的子图,要求高效实现,避免逐个拆分数据集的冗余操作。
高效实现方案
核心思路:仅执行一次PCA降维,复用降维结果,通过子图网格+布尔索引快速筛选对应组合的数据点,避免重复计算PCA,同时统一布局便于对比。
步骤1:数据预处理与PCA计算
首先提取数值特征,完成PCA降维并计算特征载荷(用于Biplot的箭头绘制):
import pandas as pd import numpy as np from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt # 加载数据集(示例数据,实际替换为完整数据集) data = pd.DataFrame({ 'species': ['Adelie', 'Adelie', 'Adelie', 'Adelie', 'Chinstrap', 'Chinstrap', 'Chinstrap', 'Gentoo', 'Gentoo', 'Gentoo'], 'bill_length_mm': [18,17,18,0,19,20,17,19,18,20], 'bill_depth_mm': [18,17,18,0,19,20,17,19,18,20], 'flipper_length_mm': [181,186,195,0,193,190,181,195,193,190], 'body_mass_g': [3750,3800,3250,0,3450,3650,3625,4675,3475,4250], 'predicted_species': ['Chinstrap','Adelie','Gentoo','Adelie','Chinstrap','Gentoo','Adelie','Chinstrap','Gentoo','Gentoo'] }) # 提取数值特征并标准化(PCA前建议标准化) num_features = ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm', 'body_mass_g'] X = data[num_features].values scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 执行PCA降维到2维 pca = PCA(n_components=2) X_pca = pca.fit_transform(X_scaled) # 计算特征载荷(用于Biplot箭头) loadings = pca.components_.T * np.sqrt(pca.explained_variance_) feature_names = num_features
步骤2:生成子图网格并绘制Biplot
创建3x3子图网格,遍历原生与预测物种的所有组合,用布尔索引筛选对应数据点,复用已计算的PCA结果绘制Biplot:
# 获取唯一物种类别 species_list = data['species'].unique() pred_species_list = data['predicted_species'].unique() # 生成所有真实-预测物种组合 combinations = [(sp, pred_sp) for sp in species_list for pred_sp in pred_species_list] # 创建3x3子图网格 fig, axes = plt.subplots(3, 3, figsize=(15, 12)) axes = axes.flatten() # 扁平化数组方便遍历 # 遍历每个组合绘制子图 for idx, (true_sp, pred_sp) in enumerate(combinations): ax = axes[idx] # 筛选当前组合的数据点 mask = (data['species'] == true_sp) & (data['predicted_species'] == pred_sp) # 绘制数据点 ax.scatter(X_pca[mask, 0], X_pca[mask, 1], alpha=0.7, label=f'{true_sp} → {pred_sp}') # 绘制Biplot特征箭头(所有子图复用同一载荷) for i, feature in enumerate(feature_names): ax.arrow(0, 0, loadings[i, 0], loadings[i, 1], color='red', alpha=0.5) ax.text(loadings[i, 0]*1.1, loadings[i, 1]*1.1, feature, color='red', fontsize=8) # 设置子图样式 ax.set_title(f'True: {true_sp} | Predicted: {pred_sp}', fontsize=10) ax.set_xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%})') ax.set_ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%})') ax.legend(fontsize=8) ax.grid(alpha=0.3) # 调整子图间距 plt.tight_layout() plt.show()
方案优势
- 高效性:仅执行一次PCA降维,所有子图复用同一结果,避免重复计算,大幅提升运行效率;
- 可对比性:3x3网格统一布局,便于直观对比不同真实-预测物种组合的数据分布差异;
- 可扩展性:若后续物种类别增加,只需调整子图网格尺寸(如4x4),核心逻辑无需修改。
内容的提问来源于stack exchange,提问作者Brie MerryWeather
相关产品推荐
相关产品推荐

