当前位置: 首页 > java >正文

主成分分析(PCA)原理与实战:从0到1彻底掌握

目录

一、PCA 是什么?

二、几何直觉:为什么要做 PCA?

三、PCA 的数学原理

步骤 1:中心化数据(零均值)

步骤 2:计算协方差矩阵

步骤 3:求协方差矩阵的特征值与特征向量

步骤 4:选取前 k 个最大特征值对应的特征向量

步骤 5:降维映射

四、每一步代表什么含义?

五、PCA Python 实现代码(无黑盒)

六、PCA C++ 实现代码(Eigen 库)

七、sklearn 一键式 PCA

八、常见问题与误区

九、应用场景

总结


        PCA(Principal Component Analysis,主成分分析)是最常用的数据降维算法之一,广泛用于数据预处理、可视化、压缩和特征提取等场景。本文将从原理、几何直觉、完整数学推导到实际 Python 和 C++ 代码实现,并且给你一个详细的例子步骤,帮助你系统理解 PCA,并真正能用起来。


一、PCA 是什么?

PCA 是一种线性降维方法,它通过寻找数据变化最大的方向,将高维数据投影到一个低维空间,在尽可能保留原始信息的同时,减少特征维度。

它的目标是:

找到一组正交向量(主成分方向),使得数据在这些方向上投影后的方差最大。


二、几何直觉:为什么要做 PCA?

假设你有一堆二维点(比如身高、体重),它们分布在某个斜向的方向上:

  • 若你用 x 或 y 分别代表样本,会有大量冗余(信息分散在两个维度)

  • 但如果你找出数据分布最“宽”的方向(即最大方差方向),你可以仅保留这一维信息

PCA 就是:

  • 找到数据协方差最大的方向(主成分)

  • 将数据映射(投影)到这些主成分上

  • 最后舍弃那些贡献信息少的维度


三、PCA 的数学原理

步骤 1:中心化数据(零均值)

对每个特征减去其平均值,变为零均值:

步骤 2:计算协方差矩阵

它反映了各个特征之间的线性相关性。

步骤 3:求协方差矩阵的特征值与特征向量

  • 特征向量 \mathbf{v}:主成分方向

  • 特征值 \lambda:投影后数据在该方向上的方差(重要性)

步骤 4:选取前 k 个最大特征值对应的特征向量

这组成降维的变换矩阵:

步骤 5:降维映射

将数据投影到主成分空间:


四、每一步代表什么含义?

步骤数学操作几何/统计意义
中心化每列减均值消除偏移,让主成分穿过原点
协方差矩阵描述特征间协变哪些特征共同变化、多余?
特征分解找主方向找最大方差方向(最能表达数据)
选特征向量取前 k 个选择“最重要”的 k 个方向
投影X 乘主方向得到新特征值(新坐标)

五、PCA Python 实现代码(无黑盒)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScalerX = np.array([[2.5, 2.4],[0.5, 0.7],[2.2, 2.9],[1.9, 2.2],[3.1, 3.0],[2.3, 2.7],[2.0, 1.6],[1.0, 1.1],[1.5, 1.6],[1.1, 0.9]
])scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
cov_matrix = np.cov(X_scaled.T)
eig_vals, eig_vecs = np.linalg.eig(cov_matrix)
W = eig_vecs[:, :2]
X_pca = X_scaled @ Wplt.scatter(X_pca[:,0], X_pca[:,1])
plt.title("PCA 降维后的数据")
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.grid()
plt.show()

六、PCA C++ 实现代码(Eigen 库)

我们使用 Eigen 这个常用的线性代数库来实现 PCA 的完整过程。

#include <iostream>
#include <Eigen/Dense>using namespace Eigen;
using namespace std;int main() {MatrixXd X(10, 2);X << 2.5, 2.4,0.5, 0.7,2.2, 2.9,1.9, 2.2,3.1, 3.0,2.3, 2.7,2.0, 1.6,1.0, 1.1,1.5, 1.6,1.1, 0.9;RowVectorXd mean = X.colwise().mean();MatrixXd X_centered = X.rowwise() - mean;MatrixXd cov = (X_centered.adjoint() * X_centered) / double(X.rows() - 1);SelfAdjointEigenSolver<MatrixXd> eig(cov);MatrixXd eig_vectors = eig.eigenvectors().rightCols(2); // 取最大两个特征向量MatrixXd X_pca = X_centered * eig_vectors;cout << "降维后的结果:\n" << X_pca << endl;return 0;
}

编译:

g++ pca.cpp -o pca -I /path/to/eigen && ./pca

七、sklearn 一键式 PCA

from sklearn.decomposition import PCApca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
print("PCA 后的形状:", X_pca.shape)

八、常见问题与误区

  1. PCA 是否适合所有数据?

    • 不适合高度非线性的情形,可考虑 Kernel PCA、t-SNE。

  2. 是否要标准化?

    • 一般要,除非各维度单位一致。

  3. 解释率怎么看?

    pca.explained_variance_ratio_  # 每个主成分解释的方差比例
    

九、应用场景

  • 特征压缩(降低维度,加速模型)

  • 数据可视化(高维 → 2D)

  • 去冗余(减少相关性)

  • 噪声抑制(只保留高方差)


总结

PCA 是一个集线性代数、统计学、几何直觉于一体的强大工具。通过这篇文章,我们不仅明白了它背后的数学原理,也掌握了从零实现到调用库函数的全过程。

建议:

  • 理解矩阵投影本质

  • 多画图直观理解方差最大方向

  • 搭配 SVD、t-SNE 等方法综合使用

希望本文对你理解 PCA 和数据降维有所帮助,欢迎点赞、评论和转发!

http://www.xdnf.cn/news/13065.html

相关文章:

  • 智能门锁申请 EN 18031 欧盟网络安全认证指南​
  • 作为测试我们应该关注redis哪些方面
  • 软件开发工程师如何在项目开发中了解学习 ISO 13485
  • AIGC 基础篇 Python基础 03 列表与条件判断
  • DeepSeek越强,Kimi越慌?
  • 【合并通感算】
  • 用户画像建模的7种机器学习方法
  • Rex-Thinker模型的核心思想、亮点和挑战
  • Solidity从入门到精通-Remix的基本使用和Solidity的基本数据类型
  • Java UDP网络通信实战指南
  • 时空网络动力学图谱分析完整解决方案
  • delphi安装SAP控件:SAPFunctionsSAPLogonControl
  • 线程中可见性ABA问题是什么如何解决
  • Redis上篇--知识点总结
  • STM32简易示波器/逻辑分析仪设计指南
  • 用虚拟机安装macos系统之后进入Boot Manager页面
  • Vue 实例的数据对象详解
  • ECS架构之Entity设计与传统OOP的碰撞思考
  • Jinja2核心应用场景及示例
  • JavaWeb-JDBC实现数据库更新操作(超简单入门版)
  • 综合态势显示 ASD-100
  • leetcode41-缺失的第一个正数
  • java复习 06
  • 写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里
  • 今日行情明日机会——20250609
  • AT模式下的全局锁冲突如何解决?
  • 【大厂机试题解法笔记】报文响应时间
  • 理解大端与小端字节序——原理、实践与网络编程
  • 发立得信息发布系统房屋信息版(php+mysql)V1.0版
  • 在Ubuntu24上采用Wine打开SourceInsight