← 返回首页
🤖

PCA主成分分析

📂 ai ⏱ 2 min 226 words

PCA主成分分析

主成分分析(Principal Component Analysis,PCA)是一种常用的无监督降维方法。它通过线性变换将高维数据投影到低维空间,同时尽可能保留数据的方差信息。PCA在数据可视化、特征提取和去噪等领域有广泛应用。

PCA的基本原理

PCA的核心思想是找到数据中方差最大的方向,这些方向称为主成分。第一主成分是数据方差最大的方向,第二主成分是与第一主成分正交且方差次大的方向,以此类推。

主成分的求解本质上是对数据协方差矩阵进行特征值分解。设数据矩阵为X,标准化后的协方差矩阵为:

C = (1/n) * X^T * X

对C进行特征值分解,得到的特征向量就是主成分方向,特征值表示对应方向上的方差大小。

使用sklearn实现PCA

import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

# 加载数据
iris = load_iris()
X = iris.data
y = iris.target

# 标准化数据(PCA对尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 创建PCA模型,保留2个主成分
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

# 查看方差解释比例
print("各主成分的方差解释比例:", pca.explained_variance_ratio_)
print("累计方差解释比例:", np.sum(pca.explained_variance_ratio_))

# 可视化降维结果
plt.figure(figsize=(8, 6))
for i, target_name in enumerate(iris.target_names):
    mask = y == i
    plt.scatter(X_pca[mask, 0], X_pca[mask, 1], label=target_name)
plt.xlabel('第一主成分')
plt.ylabel('第二主成分')
plt.title('PCA降维后的鸢尾花数据')
plt.legend()
plt.show()

选择合适的主成分数量

在实际应用中,我们需要确定保留多少个主成分。常用方法是观察累计方差解释比例,通常选择使累计方差达到85%-95%的主成分数量。

# 计算不同主成分数量对应的累计方差
pca_full = PCA()
pca_full.fit(X_scaled)

cumulative_variance = np.cumsum(pca_full.explained_variance_ratio_)

# 绘制方差解释曲线
plt.figure(figsize=(8, 5))
plt.plot(range(1, len(cumulative_variance) + 1), cumulative_variance, 'bo-')
plt.xlabel('主成分数量')
plt.ylabel('累计方差解释比例')
plt.title('PCA方差解释曲线')
plt.axhline(y=0.95, color='r', linestyle='--', label='95%方差')
plt.legend()
plt.grid(True)
plt.show()

# 选择达到95%方差的主成分数量
n_components_95 = np.argmax(cumulative_variance >= 0.95) + 1
print(f"达到95%方差需要的主成分数量: {n_components_95}")

PCA在图像压缩中的应用

PCA可以用于图像压缩,通过保留主要的主成分来减少存储空间。

from sklearn.datasets import fetch_olivetti_faces

# 加载人脸数据
faces = fetch_olivetti_faces()
X_faces = faces.data

# 使用PCA进行降维
pca_faces = PCA(n_components=100)
X_compressed = pca_faces.fit_transform(X_faces)

# 重建图像
X_reconstructed = pca_faces.inverse_transform(X_compressed)

# 比较原始图像和重建图像
fig, axes = plt.subplots(2, 5, figsize=(12, 5))
for i in range(5):
    axes[0, i].imshow(X_faces[i].reshape(64, 64), cmap='gray')
    axes[0, i].set_title('原始')
    axes[0, i].axis('off')
    axes[1, i].imshow(X_reconstructed[i].reshape(64, 64), cmap='gray')
    axes[1, i].set_title('重建')
    axes[1, i].axis('off')
plt.tight_layout()
plt.show()

print(f"压缩率: {X_faces.shape[1]}/{pca_faces.n_components_} = {X_faces.shape[1]/pca_faces.n_components_:.1f}倍")

PCA的局限性

PCA是一种线性降维方法,对于非线性结构的数据效果可能不佳。对于这类数据,可以考虑使用核PCA(Kernel PCA)或t-SNE等非线性降维方法。

from sklearn.decomposition import KernelPCA

# 核PCA用于非线性数据
kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
X_kpca = kpca.fit_transform(X_scaled)

plt.figure(figsize=(8, 6))
for i, target_name in enumerate(iris.target_names):
    mask = y == i
    plt.scatter(X_kpca[mask, 0], X_kpca[mask, 1], label=target_name)
plt.xlabel('核主成分1')
plt.ylabel('核主成分2')
plt.title('核PCA降维后的鸢尾花数据')
plt.legend()
plt.show()

PCA作为一种经典的降维方法,在机器学习和数据分析中有着重要的地位。掌握PCA的原理和应用,能够帮助我们更好地处理高维数据,发现数据的内在结构。