主成分分析(PCA)原理与实战应用
主成分分析(PCA)是一种常用的无监督学习降维技术,通过正交变换将相关变量转化为线性不相关的主成分。其核心思想是方差最大化,旨在保留数据最大信息量的同时降低维度。本文详细阐述了 PCA 的数学原理、计算步骤及优缺点,并通过 Python sklearn 库结合鸢尾花数据集与人脸图像数据进行了实战演示,展示了如何确定主成分数量及可视化降维效果,适用于图像处理、金融分析及生物信息学等领域。

主成分分析(PCA)是一种常用的无监督学习降维技术,通过正交变换将相关变量转化为线性不相关的主成分。其核心思想是方差最大化,旨在保留数据最大信息量的同时降低维度。本文详细阐述了 PCA 的数学原理、计算步骤及优缺点,并通过 Python sklearn 库结合鸢尾花数据集与人脸图像数据进行了实战演示,展示了如何确定主成分数量及可视化降维效果,适用于图像处理、金融分析及生物信息学等领域。

主成分分析(Principal Component Analysis,简称 PCA)是一种统计方法,通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量。这组新的变量称为主成分。
从直观角度理解,PCA 能够从数据中提取出最重要的特征,通过减少变量的数量来简化模型,同时保留原始数据集中的大部分信息。它是一种无监督学习算法,不需要数据标签即可进行训练。
PCA 的核心思想是寻找数据方差最大的方向作为第一主成分,然后在垂直于该方向的方向上寻找次大方差作为第二主成分,以此类推。这些方向必须是相互正交的。
这样做是为了保证降维后的数据能够保留最多的原始数据信息。方差越大,说明数据在该方向上的分布越分散,包含的信息量越多。
我们主要使用 scikit-learn 库中的 PCA 工具。除了常规的 PCA 外,它还可以执行 SparsePCA 和 TruncatedSVD。
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# 1. 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
feature_names = iris.feature_names
# 2. 数据标准化 (重要步骤)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 3. 初始化 PCA 模型
# n_components=2 表示降维到 2 维用于可视化
pca = PCA(n_components=2, random_state=42)
# 4. 拟合并转换数据
X_pca = pca.fit_transform(X_scaled)
# 5. 查看解释的方差比例
print(f"解释的方差比例:{pca.explained_variance_ratio_}")
print(f"累计解释方差比例:{np.sum(pca.explained_variance_ratio_)}")
# 6. 转换为 DataFrame 方便查看
pca_df = pd.DataFrame(data=X_pca, columns=['PC1', 'PC2'])
pca_df['target'] = y
print(pca_df.head())
下面使用 sklearn 内置的人脸数据集,直观感受 PCA 在图像压缩和特征提取上的效果。
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_olivetti_faces
from sklearn.decomposition import PCA
# 加载 Olivetti 人脸数据集
faces_data = fetch_olivetti_faces()
X = faces_data.data
# 设置参数
n_components = 50 # 保留 50 个主成分
pca = PCA(n_components=n_components, whiten=True, random_state=42)
X_pca = pca.fit_transform(X)
# 可视化部分原始图像和重构图像
n_images = 4
fig, axes = plt.subplots(2, n_images, figsize=(16, 8))
for i in range(n_images):
idx = i
# 原始图像
axes[0, i].imshow(X[idx].reshape(64, 64), cmap='gray')
axes[0, i].set_title(f'原始图像 {idx+1}')
axes[0, i].axis('off')
# 重构图像
reconstructed = pca.inverse_transform(X_pca[idx])
axes[1, i].imshow(reconstructed.reshape(64, 64), cmap='bone')
axes[1, i].set_title(f'PCA 重构 {idx+1}')
axes[1, i].axis('off')
plt.tight_layout()
plt.show()
通过对比可以看到,即使只保留了 50 个主成分,人脸的基本轮廓和特征依然清晰可见。如果保留更多主成分(如 100 个),图像会更接近原始图片;如果只保留 1 个主成分,则只能看到模糊的平均脸。
在实际应用中,如何选择保留多少个主成分?通常通过观察'解释方差比率'曲线来决定。
# 尝试不同的主成分数量
n_components_range = range(1, 100)
explained_variances = []
for n in n_components_range:
pca_temp = PCA(n_components=n)
pca_temp.fit(X_scaled)
explained_variances.append(np.sum(pca_temp.explained_variance_ratio_))
# 绘制曲线
plt.figure(figsize=(10, 6))
plt.plot(n_components_range, explained_variances, marker='o')
plt.xlabel('Number of Components')
plt.ylabel('Explained Variance Ratio')
plt.title('PCA Explained Variance vs Number of Components')
plt.grid(True)
plt.axhline(y=0.95, color='r', linestyle='--', label='95% Threshold')
plt.legend()
plt.show()
通常我们会选择一个拐点,或者设定一个阈值(如 95%),当累积解释方差达到该阈值时所需的最小主成分数即为最佳选择。
主成分分析(PCA)是机器学习和数据挖掘中不可或缺的工具。它通过线性变换实现降维,有效解决了高维数据带来的'维度灾难'问题。在使用 PCA 时,务必注意数据标准化预处理,并根据具体任务需求合理选择主成分数量。虽然 PCA 存在线性假设的局限,但在许多实际场景中,它依然是提升模型效率和可解释性的首选方案之一。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online