不愧是PCA,太强大 !!

文摘   2024-09-19 17:15   北京  

哈喽,我是kk~

主成分分析(PCA)的优势在于,它通过将高维数据映射到低维空间,最大化保留数据的方差,从而实现降维的同时减少信息损失。

主成分分析 (Principal Component Analysis, PCA) 是一种广泛应用于数据降维、特征提取的技术,尤其在高维数据集的可视化和简化方面具有重要作用。PCA的核心思想是将数据从原始坐标系转换到新的坐标系中,使得新的坐标轴是数据协方差矩阵的特征向量,且尽可能保留数据的方差信息。

1. PCA 的基本思想

PCA的核心目标是将原始数据投影到方差最大的方向上。假设有一个高维数据集,我们希望通过找到新的坐标系,使得投影后的数据尽量保留原数据的主要信息(即数据的方差)。这个新坐标系的轴称为主成分,每个主成分方向是使得数据方差最大化的方向。

2. 数据矩阵表示

设我们有一个  的数据矩阵 ,其中  是样本数量, 是特征数量。为了便于推导,我们假设数据已经中心化,即每一列的均值为零。如果没有中心化,可以通过减去每列的均值来实现:

其中, 是每列的均值向量。

3. 方差与协方差矩阵

PCA的目标是找到数据投影到某个方向上的最大方差。我们用协方差矩阵来描述数据的方差结构。

对于中心化后的数据矩阵 ,其协方差矩阵为:

协方差矩阵  是对称的  矩阵,描述了各个特征之间的线性相关性。

4. 目标:最大化投影方差

PCA的核心问题可以表述为:我们希望找到一个单位向量 ,使得数据投影到  方向上的方差最大化。具体来说,数据  在向量  上的投影是:

那么,投影的方差为:

因此,投影方差可以表示为:

我们希望最大化 ,但同时约束  是单位向量,即 

5. 拉格朗日乘子法

为了最大化目标函数 ,我们使用拉格朗日乘子法来引入约束条件 

构造拉格朗日函数:

对  关于  求导:

可以得到:

这说明  是协方差矩阵  的特征向量,而  是相应的特征值。

6. 特征值与特征向量

根据以上推导,PCA的主成分是协方差矩阵的特征向量。具体来说:

  • 协方差矩阵  的特征向量对应于数据的主成分方向。
  • 特征值  对应于投影到该主成分方向上的方差大小。

通过对协方差矩阵  进行特征值分解,我们可以找到一组正交的特征向量,它们代表数据中方差最大化的方向。特征值越大,说明对应的特征向量方向上数据的方差越大,这也意味着这个方向上包含的信息越多。

7. PCA 的步骤总结

  1. 数据中心化:将每个特征的均值从数据中减去,使得数据变为零均值。
  2. 计算协方差矩阵:计算中心化数据的协方差矩阵。
  3. 特征值分解:对协方差矩阵进行特征值分解,得到特征值和特征向量。
  4. 选取主成分:按照特征值从大到小排序,选择前  个最大的特征值对应的特征向量作为主成分方向。
  5. 降维:将原始数据投影到选取的主成分方向上,得到降维后的数据。

8. 示例:二维空间的PCA推导

假设我们有一个二维数据集 ,我们希望通过PCA将其降维到一维。

  1. 计算协方差矩阵:假设数据已经中心化,协方差矩阵为:
  1. 求解特征值和特征向量:对协方差矩阵  进行特征值分解,得到两个特征值  和  以及对应的特征向量  和 

  2. 选择主成分:选择最大的特征值  对应的特征向量  作为主成分方向。

  3. 数据投影:将原始数据投影到  方向上,得到一维数据:

9. PCA与SVD的关系

PCA还可以通过奇异值分解(SVD, Singular Value Decomposition)来实现。SVD将原始数据矩阵  分解为三个矩阵的乘积:

其中, 和  是正交矩阵, 是对角矩阵。通过SVD可以直接找到数据矩阵的主成分方向  和对应的奇异值 ,奇异值的平方就是协方差矩阵的特征值。

案例

假设我们有一个高维的虚拟数据集,数据来自不同特征维度的模拟测量值。通过PCA,我们将数据降维并进行可视化,以便观察数据在低维空间中的分布。

  1. 数据生成:创建一个包含1000个样本,具有10个特征的虚拟数据集。
  2. 数据预处理:对数据进行标准化。
  3. PCA分析:对数据进行PCA,选择前两个主成分。
  4. 可视化:生成2D和3D的复杂图形,以便更直观地理解数据的降维效果。
# 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from mpl_toolkits.mplot3d import Axes3D

# 生成虚拟数据
np.random.seed(42)
n_samples = 1000
n_features = 10

# 生成一个随机的高维数据集
X = np.random.randn(n_samples, n_features)

# 将数据打包为DataFrame
columns = [f'Feature_{i}' for i in range(1, n_features+1)]
df = pd.DataFrame(X, columns=columns)

# 打印前5行查看数据
print(df.head())

# Step 1: 数据标准化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)

# Step 2: 使用PCA降维到2个主成分
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# 创建新的DataFrame保存PCA结果
df_pca = pd.DataFrame(X_pca, columns=['PCA1''PCA2'])

# Step 3: 绘制二维PCA散点图
plt.figure(figsize=(108))
sns.scatterplot(x='PCA1', y='PCA2', data=df_pca, palette='bright', hue=df_pca.index, legend=False)
plt.title('2D PCA Scatter Plot', fontsize=18)
plt.xlabel('Principal Component 1', fontsize=14)
plt.ylabel('Principal Component 2', fontsize=14)
plt.grid(True)
plt.show()

# Step 4: 使用PCA降维到3个主成分
pca_3d = PCA(n_components=3)
X_pca_3d = pca_3d.fit_transform(X_scaled)

# 创建新的DataFrame保存3D PCA结果
df_pca_3d = pd.DataFrame(X_pca_3d, columns=['PCA1''PCA2''PCA3'])

# Step 5: 绘制三维PCA散点图
fig = plt.figure(figsize=(1210))
ax = fig.add_subplot(111, projection='3d')

# 使用散点图的颜色根据样本点的索引来区分
scatter = ax.scatter(df_pca_3d['PCA1'], df_pca_3d['PCA2'], df_pca_3d['PCA3'], 
                     c=df_pca_3d.index, cmap='rainbow', marker='o', alpha=0.8)

ax.set_title('3D PCA Scatter Plot', fontsize=18)
ax.set_xlabel('Principal Component 1', fontsize=12)
ax.set_ylabel('Principal Component 2', fontsize=12)
ax.set_zlabel('Principal Component 3', fontsize=12)

# 添加颜色条
cbar = fig.colorbar(scatter, ax=ax, shrink=0.6)
cbar.set_label('Sample Index', rotation=270, labelpad=15)

plt.show()

# Step 6: 绘制主成分的方差解释比例图
explained_variance = pca_3d.explained_variance_ratio_

plt.figure(figsize=(106))
plt.bar(range(14), explained_variance, alpha=0.6, color='g', label='Explained Variance')
plt.xlabel('Principal Components', fontsize=14)
plt.ylabel('Variance Explained (%)', fontsize=14)
plt.title('Explained Variance by Principal Components', fontsize=18)
plt.xticks(range(14), ['PC1''PC2''PC3'])
plt.grid(True)
plt.legend()
plt.show()

# Step 7: 绘制特征对主成分的贡献(PCA的载荷图)
components = pca.components_

plt.figure(figsize=(126))
sns.heatmap(components, cmap='Spectral', annot=True, cbar=True, yticklabels=['PC1''PC2'], xticklabels=columns)
plt.title('Feature Contributions to Principal Components', fontsize=18)
plt.xlabel('Original Features', fontsize=14)
plt.ylabel('Principal Components', fontsize=14)
plt.show()

  1. 生成虚拟数据:通过 np.random.randn 函数生成一个1000个样本、10个特征的高维数据集。该数据集服从标准正态分布。

  2. 数据标准化:使用 StandardScaler 将每个特征标准化为均值为0、方差为1的数据。这是PCA常用的预处理步骤,因为PCA对特征的尺度敏感。

  3. PCA降维到2个主成分:使用 PCA(n_components=2) 将数据降维到2维。这样我们可以在二维平面上绘制散点图,直观地观察数据的分布。

  4. 二维PCA散点图:使用 seaborn.scatterplot 绘制一个颜色鲜艳的二维散点图,不同样本的点根据索引值着色。

三维PCA散点图:使用 mpl_toolkits.mplot3d.Axes3D 创建一个三维散点图,并使用 cmap='rainbow'设置彩虹色渐变来区分不同的样本点。

方差解释比例图:使用柱状图展示每个主成分所解释的方差比例,能够直观地看到每个主成分的重要性。

特征对主成分的贡献图:使用热图展示原始特征对主成分的贡献。这个图展示了每个原始特征在主成分中的权重,帮助我们理解主成分与原始特征之间的关系。

通过PCA,我们将高维数据降维到低维,保留了数据的大部分信息。可视化的图形展示了降维效果,特别是二维和三维的散点图,结合鲜艳的颜色梯度,可以有效帮助理解数据的结构和分布。


kk机器学习算法
机器学习基础、计算机视觉…
 最新文章