问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

复现Nature图表:基于PCA的高维数据降维与可视化实践及其扩展

创作时间:
作者:
@小白创作中心

复现Nature图表:基于PCA的高维数据降维与可视化实践及其扩展

引用
1
来源
1.
https://developer.volcengine.com/articles/7430708468207583282

在数据分析领域,高维数据的可视化是一个关键挑战,而主成分分析(PCA)作为一种常用的数据降维工具,提供了将高维数据映射到二维或三维空间的直观方式。本文将基于Nature发表的一项研究中的图表,展示如何使用PCA对高维数据进行降维可视化,并通过边缘密度图等扩展方法丰富数据的表达效果,揭示样本的聚类模式,以更直观地理解数据的结构和潜在模式。

数据准备

首先,我们需要导入必要的库并加载数据集。这里我们使用经典的鸢尾花数据集作为示例。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False
import warnings
warnings.filterwarnings("ignore")
from sklearn.datasets import load_iris

# 鸢尾花数据集
iris = load_iris()
df_iris = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df_iris['target'] = iris.target
df_iris

鸢尾花数据集包含4个特征,原始数据在二维或三维空间中无法完整展示其结构特征。下面我们将通过PCA降维将数据维度降低,同时尽可能保留其信息,以便直观呈现不同类别的数据分布。

PCA降维

使用PCA(主成分分析)将鸢尾花数据集的4个特征降维为2个主成分,并计算每个主成分的方差贡献率,以便在二维空间中保留尽可能多的数据信息进行可视化展示。

from sklearn.decomposition import PCA
df_selected = df_iris.iloc[:, 0:4]

# 创建PCA对象,设置提取2个主成分
pca = PCA(n_components=2)

# 进行PCA降维
pca_result = pca.fit_transform(df_selected)

# 获取解释方差比率(贡献度)
explained_variance = pca.explained_variance_ratio_

# 将PCA结果保存为DataFrame,并用贡献度标记列名
pca_df = pd.DataFrame(pca_result, columns=[f"PC1 ({explained_variance[0]*100:.2f}%)", 
                                           f"PC2 ({explained_variance[1]*100:.2f}%)"])
pca_df

基础PCA降维可视化

将PCA降维后的数据与鸢尾花数据集的标签列(target)合并,并根据不同类别(0, 1, 2)绘制了二维散点图,每个类别用不同颜色(绿色、紫色、蓝色)表示,并设置了透明度以更清晰地展示数据的重叠情况。

# 将PCA后的数据与原始的分类标签合并
pca_df_with_label = pd.concat([pca_df, df_iris['target']], axis=1)

# 不同类别进行区分
categories = pca_df_with_label['target'].unique()

# 为不同类别设置颜色
colors = ['green', 'purple', 'blue']

# 创建散点图
plt.figure(figsize=(9, 9),dpi=1200)

# 为每个类别绘制散点图,使用不同颜色,透明度
for i, category in enumerate(categories):
    subset = pca_df_with_label[pca_df_with_label['target'] == category]
    plt.scatter(subset.iloc[:, 0], subset.iloc[:, 1], label=f'Category {category}', color=colors[i], alpha=0.3)

# 设置图表标题和轴标签
plt.title('PCA Scatter Plot by target')
plt.xlabel(pca_df.columns[0])
plt.ylabel(pca_df.columns[1])
plt.legend()
plt.savefig("1.pdf", format='pdf', bbox_inches='tight')
plt.show()

通过图表,可以看到不同类别在二维空间中的分布,其中PC1(92.46%)和PC2(5.31%)是两个主要的主成分,分别展示了数据中的主要和次要变异趋势。可视化结果表明,不同类别的样本在降维后的二维空间中形成了清晰的聚类,显示出数据结构的内在模式和类别间的可分性。

带边缘密度分布的PCA降维可视化

通过Seaborn将PCA降维后的数据绘制为散点图,并在顶部和右侧叠加了类别密度曲线,以展示各类数据在主成分轴上的分布趋势与重叠情况。

import seaborn as sns

# 设置调色板为绿、紫、蓝三种颜色
palette = ['green', 'purple', 'blue']

# 创建JointGrid对象
g = sns.JointGrid(data=pca_df_with_label, x=pca_df.columns[0], y=pca_df.columns[1], hue='target', palette=palette)

# 绘制散点图,移除图例
g.plot_joint(sns.scatterplot, s=40, alpha=0.3, legend=False)

# 绘制x轴的边缘密度图,移除图例
sns.kdeplot(data=pca_df_with_label, x=pca_df.columns[0], hue='target', ax=g.ax_marg_x, fill=True, common_norm=False, palette=palette, alpha=0.3, legend=False)

# 绘制y轴的边缘密度图,移除图例
sns.kdeplot(data=pca_df_with_label, y=pca_df.columns[1], hue='target', ax=g.ax_marg_y, fill=True, common_norm=False, palette=palette, alpha=0.3, legend=False)
g.fig.suptitle('PCA Scatter Plot with Stacked Marginal Density')
plt.savefig("2.pdf", format='pdf', bbox_inches='tight', dpi=1200)
plt.show()

相比于单纯的散点图,这种可视化方式增加了每个类别的边缘分布信息,使数据的分布特点更加直观清晰。

带二维核密度估计的PCA降维可视化

结合散点图和二维核密度估计(KDE),在展示数据点的同时,通过核密度轮廓进一步揭示了不同类别的分布趋势和集中区域,帮助更清晰地观察类别间的重叠与分离情况。

# 不同类别进行区分
categories = pca_df_with_label['target'].unique()

# 为每个类别设置颜色,分别为黄、紫、蓝
colors = ['green', 'purple', 'blue']

# 创建散点图和边缘密度图
plt.figure(figsize=(9, 9), dpi=1200)

# 为每个类别绘制散点图,使用不同颜色
for i, category in enumerate(categories):
    subset = pca_df_with_label[pca_df_with_label['target'] == category]
    plt.scatter(subset.iloc[:, 0], subset.iloc[:, 1], label=f'Category {category}', color=colors[i], alpha=0.3)

    # 绘制边缘密度图(二维核密度估计),使用相同颜色
    sns.kdeplot(x=subset.iloc[:, 0], y=subset.iloc[:, 1], color=colors[i], shade=True, thresh=0.05, alpha=0.3)

# 设置图表标题和轴标签
plt.title('PCA Scatter Plot with Marginal Density by target')
plt.xlabel(pca_df.columns[0])
plt.ylabel(pca_df.columns[1])
plt.legend(title='Categories')
plt.savefig("3.pdf", format='pdf', bbox_inches='tight')
plt.show()

这种可视化方式是PCA可视化的扩展,通过增加密度信息,使数据的分布特征在降维空间中得到更全面的表达。

PCA双标图(Biplot)降维可视化

PCA双标图,在展示不同类别样本散点分布的同时,用箭头表示每个特征在主成分空间中的投影方向及其对主成分的贡献大小,帮助理解各特征在数据降维中的作用。

labels = df_iris['target']  # 类别标签列

# 定义类别的颜色映射
categories = labels.unique()
colors = ['green', 'purple', 'blue']
color_map = {category: color for category, color in zip(categories, colors)}

# 创建双标图
plt.figure(figsize=(10, 7), dpi=1200)

# 绘制样本的散点图,使用类别的颜色映射
for category in categories:
    subset = pca_df[labels == category]
    plt.scatter(subset.iloc[:, 0], subset.iloc[:, 1], alpha=0.5, color=color_map[category], label=f'Category {category}')

# 获取PCA组件(特征向量)
components = pca.components_

# 绘制特征向量(箭头)
for i, feature in enumerate(df_selected.columns):
    plt.arrow(0, 0, components[0, i] * max(pca_result[:, 0]), components[1, i] * max(pca_result[:, 1]), 
              color='red', head_width=0.1, head_length=0.1)
    plt.text(components[0, i] * max(pca_result[:, 0]) * 1.1, 
             components[1, i] * max(pca_result[:, 1]) * 1.1, 
             feature, color='black')

# 设置轴标签,并调整标签的位置
plt.xlabel(f"PC1 ({explained_variance[0]*100:.2f}%)", labelpad=180)  # x轴标签设置下方
plt.ylabel(f"PC2 ({explained_variance[1]*100:.2f}%)", labelpad=240)  # y轴标签设置左侧

# 只显示x轴和y轴,不显示网格,并确保轴正确放置
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['bottom'].set_position('zero')
plt.gca().spines['left'].set_position('zero')
plt.legend()
plt.savefig("4.pdf", format='pdf', bbox_inches='tight')
plt.show()

这种双标图进一步丰富了PCA可视化的表现力,是对基础散点图的扩展,揭示了特征与样本之间的关系。

总结

通过上述多种PCA可视化方法的展示,读者可以根据自身的分析需求选择合适的绘图方式。同时,不同的可视化方法还可以灵活组合,例如在绘制PCA双标图的同时,叠加二维核密度估计或边缘密度分布,以进一步丰富数据的表达效果。这些可视化不仅能够帮助更直观地理解数据结构,还能揭示特征与类别之间的潜在关系。此外,虽然PCA是常用的降维方法,但它并非唯一选择,读者还可以尝试t-SNE等其他降维技术,根据数据特点和分析需求选择最适合的方法进行可视化与解读。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号