想象你站在公园草坪上,100位朋友正散落在各处聊天。你想用手机把他们全部框进一张合影,但无论站在哪个角度,总有人在照片里挤成一团、难以分辨。于是你开始绕着人群转圈,寻找一个“所有人铺得最开”的拍摄位置——这个角度拍出的照片信息量最大,谁都挡不住谁。PCA(主成分分析)做的就是这件事,只不过它是在“数据的坐标系”里转圈找角度。 现实中的数据常常有几十甚至上万维特征,就像每个朋友身上挂了一串标签:身高、体重、鞋码、发量、消费水平……标签太多反而让人眼花缭乱,算法也变得又慢又笨。PCA的第一步是看清所有特征之间如何联动(协方差矩阵),第二步是解出几个互相独立的“主方向”(特征分解),第三步是沿着主方向给数据“拍照”(投影降维)。每个主方向都有一个“散开得分”(特征值),告诉你这个方向能保留多少信息。 这篇文章从协方差出发,带你一步步吃透方差最大化、特征分解、主成分选取、信息损失度量,再看清PCA与SVD的关系,最后落成可以实际运行的代码。

岗位关联

对AI从业者来说,PCA是特征工程与数据预处理的基本功。理解它,你才能判断模型输入里哪些维度是噪声、哪些是主线,用最少的维度留住最多的信息。

目录
  1. 可视化演示
  2. 降维动机——为什么数据需要“减肥”
  3. 方差与投影——给数据选个“散得最开”的角度
  4. 协方差矩阵——记录所有“联动关系”的账本
  5. 特征分解——从账本中解出“主方向”
  6. 主成分选取——如何决定留下几个方向
  7. 信息损失度量——降维的代价
  8. PCA与SVD——殊途同归的两条路
  9. 算法实现步骤——从零搭建PCA流水线
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

三模式展示最大方差投影方向(PC1/PC2)、协方差矩阵特征分解(C=VΛVᵀ)、Scree图方差解释比与主成分选择,揭示PCA降维数学原理。

本节配有交互动效(进入视口后自动加载,约 3KB)。

'+captions[0]+'

降维动机——为什么数据需要“减肥”

想象你去动物园看动物,管理员递给你一张超详细清单,每只动物登记了30项指标:体重、身高、毛色值、尾巴长度、耳阔、奔跑速度……清单信息确实“全”,但你一眼望去只觉得头晕,根本分不清哪些动物是一类。信息太多反而成了负担,这就是高维数据的困境。

在机器学习里,这种现象被称为“维度灾难”。特征从2维涨到1000维时,样本之间的距离会趋向于彼此相等,任何依赖距离的算法都会失效;训练模型所需的数据量呈指数级膨胀;二维、三维可视化更是无从谈起。于是人们迫切地希望:在减少维度的同时,尽量保留数据“最重要的差异”。

PCA给出了一套优雅的答案:把数据看作高维空间中的一群点,用一组正交方向重新描述它们,只保留“散开程度”最大的几个方向。散开程度用方差衡量,因为方差代表信息量——如果某个方向上方差为0,说明所有样本在这个方向上毫无差别,这个方向就没有信息。降维就是找到方差最大的若干方向,把数据投影上去,得到新的低维表示。

回到动物园的比喻:与其捧着30列指标逐个比对,不如顺着“体型大小”“运动习性”这样两三个综合方向去观察,大部分动物依然能被清楚地区分开。理解了“降维是为了保留最大差异”这个动机,接下来所有的数学推导,都是在围着“方差”这两个字打转。

方差与投影——给数据选个“散得最开”的角度

你拿着手机绕着人群转圈,每换一个角度就比画一下:哪张照片里朋友们的横向位置铺得最开?在PCA的世界里,“角度”由一个单位方向向量 \(w\) 表示,“铺得开不开”由数据投影到该方向后的方差衡量。

假设数据已经做了中心化处理(每个样本减去均值),把样本 \(x_i\) 向方向 \(w\) 投影,会得到一个标量 \(z_i=w^T x_i\)。这些 \(z_i\) 构成一维新数据,它们的方差就是投影方差。PCA要找的 \(w\),就是让这个方差达到最大的单位向量。神奇的是,投影方差可以改写成非常简洁的二次型:

在人群合影的场景里,\(w\) 就是你举起相机的方向,\(w^T\Sigma w\) 就是照片里人群铺开的“松散程度”。PCA这场寻宝,目标只有一个:找出让这个值最大的那个方向。

Var(z)=1n∑i=1n(wTxi)2=wT(1n∑i=1nxixiT)w=wTΣw\displaystyle \mathrm{Var}(z)=\frac{1}{n}\sum_{i=1}^{n}(w^T x_i)^2=w^T\left(\frac{1}{n}\sum_{i=1}^{n}x_i x_i^T\right)w=w^T\Sigma w
这个式子把“找最大方差方向”变成了“让二次型 \(w^T\Sigma w\) 最大”的数学问题,中间的 \(\Sigma\) 就是接下来要重点认识的协方差矩阵。
  1. 投影标量样本 \(x_i\) 在单位向量 \(w\) 方向的投影是一个数,相当于“朋友在某角度下的横向坐标”。
    zi=wTxiz_i=w^T x_i
  2. 原方差展开投影后所有 \(z_i\) 的平方取平均,就是该方向上的方差,直接对应“人群铺开的程度”。
    1n∑i=1n(wTxi)2\frac{1}{n}\sum_{i=1}^{n}(w^T x_i)^2
  3. 提取二次型把平方展开、把 \(w\) 提到外面,中间剩下的括号里就是对数据“两两联动关系”的汇总。
    wT(1n∑i=1nxixiT)ww^T\left(\frac{1}{n}\sum_{i=1}^{n}x_i x_i^T\right)w
  4. 协方差矩阵登场括号里的整体就是协方差矩阵 \(\Sigma\),于是方差化简为 \(w^T\Sigma w\)。
    wTΣww^T\Sigma w

协方差矩阵——记录所有“联动关系”的账本

拍照前,你得先摸清人群的空间分布。协方差矩阵就是这张“人群分布账本”:第 \(i\) 行第 \(j\) 列记录第 \(i\) 个特征与第 \(j\) 个特征之间的联动关系。数值为正,说明两个特征同向变化(个子高的人往往鞋码大);为负说明反向变化(运动越多脂肪越少);接近0说明二者基本无关。

对于 \(d\) 维数据,协方差矩阵是一个 \(d\times d\) 的对称矩阵。对角线上的元素是每个特征自己的方差,非对角线是特征两两之间的协方差。它的标准定义式如下:

协方差矩阵有一个极好的数学性质:它是对称且半正定的。半正定保证所有特征值不小于0,这为后续特征分解扫清了障碍。把协方差矩阵“对角化”,相当于把账本换一套坐标轴,让它变成只有对角线有数字的简洁形式——这正是“主成分分析”这个名称的由来:把坐标轴旋转到“主力方向”上。

就像记账时把杂乱的流水重新按“主账户”归类和汇总,协方差矩阵对角化之后,每个对角线数字就是一条主线的“重要程度”,其余位置全部归零,账目清爽又直观。

Σ=1n∑i=1n(xi−μ)(xi−μ)T\displaystyle \Sigma=\frac{1}{n}\sum_{i=1}^{n}(x_i-\mu)(x_i-\mu)^T
这个矩阵把所有样本的“偏离程度”汇总成一张表,是PCA全部信息的来源。
  1. 均值向量\(\mu\) 是每个特征的平均值,代表人群的“地理中心”。
    μ=1n∑i=1nxi\mu=\frac{1}{n}\sum_{i=1}^{n}x_i
  2. 中心化样本每个样本减去均值,相当于把坐标原点移到数据中心,让“偏离”有了参照。
    xi−μx_i-\mu
  3. 外积矩阵中心化向量与其转置相乘,得到一个 \(d\times d\) 矩阵,编码了这单个样本内部两两特征的关系。
    (xi−μ)(xi−μ)T(x_i-\mu)(x_i-\mu)^T
  4. 取平均对全部样本的外积求平均,就得到协方差矩阵 \(\Sigma\)。
    Σ=1n∑i=1n(xi−μ)(xi−μ)T\Sigma=\frac{1}{n}\sum_{i=1}^{n}(x_i-\mu)(x_i-\mu)^T

特征分解——从账本中解出“主方向”

账本拿到手,怎么找出“人群散得最开的主方向”?答案是特征分解。它把协方差矩阵拆解成“旋转、拉伸、逆旋转”三个标准动作,让你一眼看清每个方向的力度。

特征分解定理保证:对于对称矩阵 \(\Sigma\),一定存在正交矩阵 \(Q\) 和对角矩阵 \(\Lambda\),使得:

这里隐藏着PCA最关键的一步:对任意单位向量 \(w\),\(w^T\Sigma w\) 衡量该方向的方差;当 \(w\) 恰好是某个特征向量 \(q_j\) 时,这个值正好等于对应的特征值 \(\lambda_j\)。因此,“找最大方差方向”就等于“找最大特征值对应的特征向量”——这就是第一主成分。

特征分解就像从人群关系账本里解出几条互相垂直的“主街道”,每条街道都贴着醒目的“拥挤程度”标签(特征值)。散得最开的那条主街道,就是你的第一主成分,路线完全确定,不再需要举着手机绕圈试角度。

Σ=QΛQT\displaystyle \Sigma=Q\Lambda Q^T
其中 \(Q\) 的每一列是一个单位正交特征向量(主方向),\(\Lambda\) 对角线上的 \(\lambda_j\) 是该方向上的方差(特征值)。
  1. 特征向量矩阵\(Q\) 的每一列 \(q_j\) 都是一个单位正交特征向量,也就是一个候选的“主街道”方向。
    Q=[q1,q2,…,qd]Q=[q_1,q_2,\ldots,q_d]
  2. 特征值对角矩阵\(\Lambda\) 只有对角线有值,\(\lambda_j\) 越大,说明数据沿 \(q_j\) 方向散得越开。
    Λ=diag(λ1,λ2,…,λd)\Lambda=\mathrm{diag}(\lambda_1,\lambda_2,\ldots,\lambda_d)
  3. 正交性质\(Q\) 是正交矩阵,满足 \(Q^TQ=I\),因此转置就是逆矩阵,分解才能“无损还原”。
    QTQ=I,QT=Q−1Q^T Q=I,\quad Q^T=Q^{-1}
  4. 分解公式整个矩阵被拆成三个动作:先用 \(Q^T\) 旋转坐标轴,再沿各轴拉伸 \(\lambda_j\) 倍,最后用 \(Q\) 旋转回来。
    Σ=QΛQT\Sigma=Q\Lambda Q^T

主成分选取——如何决定留下几个方向

你不可能把无数张角度的照片都存进手机。PCA的做法是把特征值从大到小排序,取前 \(k\) 个对应的特征向量组成投影矩阵。问题是:这个 \(k\) 到底取多少?

每个特征值 \(\lambda_j\) 表示数据沿第 \(j\) 个主成分方向的方差,而所有特征值之和恰好等于数据的总方差。于是可以用“累计贡献率”来衡量前 \(k\) 个方向合起来保住了多大比例的信息:

选定 \(k\) 之后,把前 \(k\) 个特征向量并列排成投影矩阵 \(W=[w_1,w_2,\ldots,w_k]\),降维后的数据就是 \(Z=X_{\mathrm{std}}W\)。另一个辅助工具是“碎石图”:画出特征值随序号下降的曲线,曲线从某个位置开始变得平缓,说明后面的方向基本都是噪声。

这就像你选照片时的策略:优先挑一张“人物铺得最开”的主图,再顺手挑几张角度互补的辅助图,累计贡献率告诉你这几张图合起来覆盖了人群多大范围的散布情况。点到为止,够用就好。

ηk=λ1+λ2+⋯+λkλ1+λ2+⋯+λd\displaystyle \eta_k=\frac{\lambda_1+\lambda_2+\cdots+\lambda_k}{\lambda_1+\lambda_2+\cdots+\lambda_d}
累计贡献率 \(\eta_k\) 越接近1,说明降维丢的信息越少;工程上通常要求达到85%~95%。
  1. 特征值降序先把所有特征值从大到小排队,确保前面的方向信息量最大。
    λ1≥λ2≥⋯≥λd\lambda_1\ge\lambda_2\ge\cdots\ge\lambda_d
  2. 被保留的方差前 \(k\) 个特征值求和,代表降维后留下的信息总量。
    ∑j=1kλj\sum_{j=1}^{k}\lambda_j
  3. 总方差所有特征值求和,就是原始数据的总方差。
    ∑j=1dλj\sum_{j=1}^{d}\lambda_j
  4. 求比值两者相除得到累计贡献率,也就是“前k个方向讲完了整个故事的多大比例”。
    ηk=∑j=1kλj∑j=1dλj\eta_k=\frac{\sum_{j=1}^{k}\lambda_j}{\sum_{j=1}^{d}\lambda_j}

信息损失度量——降维的代价

如果硬要站在人群的正侧方拍一张“一维照片”,所有人都会重合成一条线,照片里根本分不清谁是谁——这是信息损失的极端案例。降维本质上是拿 \(k\) 个方向去近似原始 \(d\) 个方向,代价一定存在,关键要能精确衡量。

把低维表示映射回原空间,会得到重构点 \(\hat{x}_i\)。重构误差就是所有样本原始位置与重构位置距离平方的总和。PCA最漂亮的性质之一是:这个误差不需要逐点计算距离,它恰好等于被丢弃的后 \(d-k\) 个特征值之和:

这一等式给工程实践带来巨大便利:不需要跑一遍重构流程,只看被丢弃的特征值合计,就能预判“压缩后糊不糊”。\(k\) 越大,信息保留越多,但降维压缩的收益越小;\(k\) 越小则反之。所以选择 \(k\) 本质上是一个工程权衡:在压缩率和信息保留率之间找平衡点。

这就像手机相册里存合影时选择图片压缩率:压缩太狠细节模糊,人物面目全非;压缩太轻占满内存。重构误差就是那把“模糊度标尺”,让你能理性地决定到底保留几个主成分。

Erecon=∑i=1n∥xi−x^i∥2=∑j=k+1dλj\displaystyle E_{\mathrm{recon}}=\sum_{i=1}^{n}\|x_i-\hat{x}_i\|^2=\sum_{j=k+1}^{d}\lambda_j
被丢弃的特征值越大,重构误差越大;特征值接近0的方向被丢弃后,几乎不产生损失。
  1. 重构点低维坐标通过投影矩阵的转置映射回原空间,得到对原始位置的“估算”。
    x^i=WWTxi\hat{x}_i=W W^T x_i
  2. 距离平方和每个样本原位置与重构位置做差、取范数平方,再对所有样本求和。
    ∑i=1n∥xi−x^i∥2\sum_{i=1}^{n}\|x_i-\hat{x}_i\|^2
  3. 特征值等价由于正交性,所有交叉项抵消,误差之和恰好压缩成后 \(d-k\) 个特征值的求和。
    ∑j=k+1dλj\sum_{j=k+1}^{d}\lambda_j

PCA与SVD——殊途同归的两条路

去公园有几条路:一条绕远路看风景,一条走快捷高速。PCA与SVD的关系正是如此:PCA通过特征分解协方差矩阵找主方向,SVD则直接分解原始数据矩阵,通常更高效、更稳定。

对中心化后的数据矩阵 \(X\)(\(n\times d\)),SVD将其分解为 \(X=U S V^T\),其中 \(U\) 是左奇异向量矩阵、\(S\) 是奇异值对角矩阵、\(V\) 是右奇异向量矩阵。SVD与PCA的联系藏在一个恒等式里:

工程实现上的差异也很实际:先算协方差矩阵 \(X^T X\) 再特征分解,相当于把数据“平方”了一下,数值误差会被放大;而SVD直接处理原始矩阵,条件数更友好。这也是为什么 scikit-learn 的 PCA 底层默认调用 LAPACK 的 SVD 实现——它不是“另一种PCA”,而是“更稳的PCA”。

看待同一个公园,你可以绕路看风景求出主街方向(特征分解),也可以走高速直达(SVD)。两条路殊途同归,但SVD这条路更平坦,很少在半路“翻车”。

X=U S VT,XTX=V STS VT,λj=sj2\displaystyle X=U\,S\,V^{T},\qquad X^{T}X=V\,S^{T}S\,V^{T},\qquad \lambda_j=s_j^2
右边的 \(V\) 正是PCA中的特征向量矩阵,\(S\) 对角线上的奇异值 \(s_j\) 的平方就是特征值 \(\lambda_j\)。
  1. SVD分解任意形状的矩阵 \(X\) 都能分解为左奇异向量、奇异值、右奇异向量三部分。
    X=U S VTX=U\,S\,V^{T}
  2. 散布矩阵计算 \(X^T X\) 时,由于 \(U\) 是正交矩阵,交叉项会全部消失。
    XTX=V STS VTX^{T}X=V\,S^{T}S\,V^{T}
  3. 特征值对应对比PCA的协方差特征分解 \(X^T X=V\Lambda V^T\),可得 \(\lambda_j=s_j^2\)。
    λj=sj2\lambda_j=s_j^2

算法实现步骤——从零搭建PCA流水线

最后我们把整套“合影流程”写成一份标准操作手册。PCA落地只需四步,每一步对应前面学过的一个概念:

第一步,标准化:每个特征减去均值、除以标准差,防止“体重80kg”这种大数值特征碾压“身高1.8m”这种小数值特征。第二步,计算协方差矩阵 \(\Sigma\)。第三步,对 \(\Sigma\) 做特征分解,按特征值降序取前 \(k\) 个特征向量组成投影矩阵 \(W\)。第四步,投影:\(Z=X_{\mathrm{std}}W\),得到降维后的新数据。

实现时有个关键细节:标准化用的均值和标准差必须来自训练集,测试集不得重新计算,否则会造成数据泄漏,评估结果虚高。另外,现代工具如 scikit-learn 支持直接传 PCA(n_components=0.95),它会自动按累计贡献率选择 \(k\)。

全套流程下来,你就像拥有了一台自动化的“最佳合影机”:先校准每位朋友的站位(标准化),再建立人群关系账本(协方差矩阵),解出主方向(特征分解),最后按下快门输出低维合影(投影)。四步环环相扣,PCA从此不再是黑盒。

Z=XstdW,W=[w1,w2,…,wk]\displaystyle Z=X_{\mathrm{std}}W,\qquad W=[w_1,w_2,\ldots,w_k]
这一套流程就是PCA的标准流水线,也是后面Python演示部分的核心逻辑。
  1. 标准化数据减均值、除标准差,让所有特征处在同一尺度。
    Xstd=X−μσX_{\mathrm{std}}=\frac{X-\mu}{\sigma}
  2. 投影矩阵前 \(k\) 个特征向量按列拼接,形状为 \(d\times k\)。
    W=[w1,w2,…,wk]W=[w_1,w_2,\ldots,w_k]
  3. 降维结果标准化数据与投影矩阵相乘,得到 \(n\times k\) 的低维表示。
    Z=XstdWZ=X_{\mathrm{std}}W

AI 应用场景

人脸识别中的特征脸

阶段:特征工程

解决的问题:一张64×64的灰度人脸图像有4096维,直接计算像素距离不仅慢,还容易受光照、表情等噪声干扰。传统做法把每个像素当独立特征,完全忽略了像素之间的强关联。

具体案例:在ORL人脸数据集上,用PCA把4096维降到100维。PCA解出的前几个特征向量对应“基础脸型”(即特征脸),任何人脸都能用100个系数近似重构。识别时只比较100维系数,速度和准确率都大幅提升。

基因表达谱的探索性分析

阶段:探索性数据分析

解决的问题:基因表达数据动辄两万个基因、却只有几十个样本,绝大多数基因只是测量噪声。传统方法逐基因做假设检验会掉入多重比较陷阱,且无法从全局把握样本结构。

具体案例:在肿瘤转录组数据上做PCA,把两万维降到二维,绘制散点图后发现正常样本与癌变样本沿着第一主成分方向自然分开。生物学家直接看图就能获得洞察,再针对性地做差异基因筛选。

推荐系统中的截断SVD

阶段:模型预处理与降维

解决的问题:用户-物品评分矩阵极度稀疏,维度高达百万级,直接做协同过滤计算量爆炸且容易过拟合。PCA/SVD恰好可以把用户和物品同时映射到共享的低维隐空间。

具体案例:Netflix推荐竞赛中,对用户-电影评分矩阵做截断SVD,得到约20维的用户隐因子和电影隐因子,然后计算余弦相似度做召回。本质上与PCA同源:右奇异向量就是“电影的隐主成分”。

Python 演示

python47 行
import numpy as np  class PCA:    """手写 PCA:从协方差矩阵特征分解出发"""     def __init__(self, n_components):        self.n_components = n_components        self._mean = None        self._std = None        self._eigvals = None        self._eigvecs = None        self.explained_ratio = None     def fit(self, X):        self._mean = np.mean(X, axis=0)        self._std = np.std(X, axis=0)        Xs = (X - self._mean) / (self._std + 1e-8)        cov = np.cov(Xs, rowvar=False, bias=True)        vals, vecs = np.linalg.eigh(cov)        order = np.argsort(vals)[::-1]        self._eigvals = vals[order]        self._eigvecs = vecs[:, order]        self.explained_ratio = self._eigvals / np.sum(self._eigvals)        return self     def transform(self, X):        Xs = (X - self._mean) / (self._std + 1e-8)        W = self._eigvecs[:, :self.n_components]        return Xs @ W     def fit_transform(self, X):        self.fit(X)        return self.transform(X)  if __name__ == "__main__":    rng = np.random.RandomState(42)    t = np.linspace(0, 4 * np.pi, 300)    X = np.column_stack([t * np.cos(t), t * np.sin(t)])    X[:, 1] += X[:, 1] * 0.5    X += rng.randn(300, 2) * 0.8     pca = PCA(n_components=1)    Z = pca.fit_transform(X)    print("保留比例:", round(pca.explained_ratio[0], 4))    print("降维后形状:", Z.shape)
目的:实现一个从零手写的PCA类,用协方差矩阵特征分解完成数据降维,并用螺旋加噪声数据验证降维效果。
  1. cov = np.cov(Xs, rowvar=False, bias=True)计算协方差矩阵,bias=True 表示除以 \(n\) 而非 \(n-1\),与PCA教材公式保持一致。
  2. vals, vecs = np.linalg.eigh(cov)对对称矩阵做特征分解,返回升序的特征值和对应的特征向量。
  3. order = np.argsort(vals)[::-1]把特征值索引按从大到小排序,确保第一主成分对应最大方差。
  4. self.explained_ratio = self._eigvals / np.sum(self._eigvals)每个主成分的方差占比,累加后就是累计贡献率。
  5. W = self._eigvecs[:, :self.n_components]只取前 \(k\) 个特征向量组成投影矩阵。
  6. return Xs @ W标准化数据与投影矩阵相乘,完成从高维到低维的映射。

常见误区

误区数据减去均值就够了,标准化会把原始分布形状改掉,我都是直接算协方差矩阵的。

正解如果特征量纲差异巨大(比如“体重80”和“身高1.8”),协方差矩阵会被量纲大的特征完全主导,主成分几乎只反映这一个特征,其他特征全被淹没。标准化让每个特征拥有平等的发言权,PCA才能发现真正综合的方向。注意:标准化后主成分不再保留原始量纲,但通常这正是我们想要的。

为何常见:初学者容易把“中心化”和“标准化”混为一谈,以为减均值就解决了尺度问题,忽略了特征之间单位不同的影响。

误区PCA选出的主成分不就是最重要的几个原始特征吗?我可以直接看系数挑几列留下来。

正解主成分是全体原始特征的线性组合。第一个主成分可能同时用到了身高、体重、鞋码各一部分权重,它是一个“合成变量”,不是原始特征里的某一个。直接挑几列原始特征那是“特征选择”,与PCA这种“特征提取”是两条完全不同的技术路线。

为何常见:“降维”两个字容易让人望文生义,以为像数据库删字段一样挑几列留下,实际上PCA输出的是全新坐标系下的坐标。

误区PCA去掉噪声后模型应该更准,所以我每次建模前都无条件先跑一遍PCA。

正解PCA是无监督方法,它只最大化方差,完全不看类别标签。某个方向上方差很大,但两类样本在这个方向上可能完全重叠;而某个方差很小的方向,恰恰可能是区分两类的最佳分界线。PCA丢掉的正是对分类最有用的方向。若要利用类别信息降维,应该考虑LDA等有监督方法。

为何常见:把“方差大=信息多”过度推广成“方差大=对任务有用”,忽略了任务目标与方差最大化并不总是一致。

误区第一主成分特征值最大,信息量肯定最多,我直接用第一个主成分就行了,剩下的都是噪声。

正解第一主成分只是“单方向方差最大”,不代表它占总方差的比例一定高。有的数据集第一个主成分只占30%方差,要保到90%可能需要前十甚至前二十个。选几个要看累计贡献率曲线和任务需求,不能拍脑袋只留一个。

为何常见:把“最大”误解成“最好且唯一”,忽略了方差占比的绝对意义——最大不等于足够。

误区scikit-learn 的 PCA 底层用的是 SVD,所以我只要会调参就行,协方差特征分解那套老方法没必要学。

正解特征分解和SVD在数学上是等价的,只是工程实现上SVD数值更稳定、避免显式构造 \(X^T X\) 带来的误差放大。但恰恰是特征分解提供了“特征向量=主方向”“特征值=方向方差”这些最直观的概念,SVD里的右奇异向量、奇异值平方等概念都是借助特征分解才能讲清楚。两者互为表里,不是新旧取代关系。

为何常见:被工具库的默认实现带偏,误以为“底层用什么算法”就等于“唯一的正统原理”,忽略了概念层与实现层的区别。

面试题

Q1. PCA的核心优化目标是什么?

单选题 · easy

  • A.最大化类别之间的可分性
  • B.最大化投影后的样本方差← 正确答案
  • C.最小化所有特征的均值
  • D.最大化特征间的相关系数

答案:B。PCA在正交约束下寻找让投影方差最大的方向,B正确。A是LDA(线性判别分析)的目标;C与方差无关;D描述的是相关关系,也不是PCA的目标。

Q2. 协方差矩阵对角线上的元素表示什么?

单选题 · easy

  • A.两个不同特征的协方差
  • B.每个特征自身的方差← 正确答案
  • C.数据样本的总个数
  • D.特征向量的长度

答案:B。协方差矩阵对角线上是每个特征自己的方差,非对角线才是特征两两之间的协方差。就像人群关系账本里,对角线上写的是“某条街自己有多挤”,不是街与街之间的关联。

Q3. PCA中第一主成分对应的是( )

单选题 · mid

  • A.最大特征值对应的特征向量← 正确答案
  • B.最小特征值对应的特征向量
  • C.数据均值最大的那个维度
  • D.方差最小的方向上的单位向量

答案:A。第一主成分是方差最大的方向,而特征值恰好等于对应方向的方差,所以它对应协方差矩阵最大特征值的特征向量。B是最后丢弃的方向,D与目标完全相反。

Q4. 为什么PCA之前通常要做标准化?

单选题 · mid

  • A.让数据满足高斯分布
  • B.防止量纲差异主导协方差← 正确答案
  • C.使协方差矩阵变成单位矩阵
  • D.减少特征数目以加速计算

答案:B。如果特征量纲差异大,协方差矩阵会被大数值特征主导,主成分只反映这一个特征。标准化让各特征平等参与。它与高斯分布无关,也不会让协方差变成单位阵。

Q5. 累计贡献率的计算公式中,分母是( )

单选题 · mid

  • A.前k个特征值之和
  • B.所有特征值之和← 正确答案
  • C.被丢弃的特征值之和
  • D.特征向量模长之和

答案:B。累计贡献率是“前k个特征值之和”除以“所有特征值之和”,等于被保留的信息比例。分母代表总方差,分子是被留下的那部分方差。

Q6. 关于主成分,下列说法正确的有( )

多选题 · mid

  • A.不同主成分之间互相正交← 正确答案
  • B.主成分是原始特征的线性组合← 正确答案
  • C.主成分个数可以超过原始维度
  • D.主成分方向由特征向量给出← 正确答案

答案:ABD。协方差矩阵对称,特征向量必两两正交,所以A对;投影过程就是做线性组合,B对;主成分方向就是特征向量,D对;投影矩阵的列数最多等于原始维度,C错。

Q7. 降维到k维后,PCA的重构误差等于( )

单选题 · hard

  • A.前k个特征值的总和
  • B.丢弃特征值的总和← 正确答案
  • C.所有特征值的乘积
  • D.协方差矩阵的整体迹

答案:B。重构误差等于被丢弃的后 \(d-k\) 个特征值之和。前k个特征值之和代表保留的信息,不是误差;所有特征值之和或乘积更不是误差。

Q8. 关于PCA与SVD的关系,正确的有( )

多选题 · hard

  • A.右奇异向量也是特征向量← 正确答案
  • B.奇异值平方等于特征值← 正确答案
  • C.SVD避免构造协方差矩阵← 正确答案
  • D.SVD只能用于方阵运算

答案:ABC。由 \(X^T X=V S^T S V^T\) 可知右奇异向量就是 \(X^T X\) 的特征向量、奇异值平方等于特征值。SVD直接分解原始矩阵,所以可以避免显式构造协方差矩阵,也不要求矩阵是方阵,D错。

Q9. 用PCA处理人脸图像,n_components=50 相比 n_components=100( )

单选题 · mid

  • A.保留更多信息重构误差更小
  • B.保留更少信息重构误差更大← 正确答案
  • C.训练时间必然更短一些
  • D.主成分方向完全不同

答案:B。主成分按方差从大到小排列,取50个保留的信息一定比100个少,重构误差也更大。训练时间取决于数据规模和算法实现,不一定更短;前50个主成分方向在两个设置下是相同的,D错。

Q10. 用训练集拟合PCA后,对测试集做标准化时,标准差应使用( )

单选题 · extreme

  • A.测试集自己的标准差
  • B.训练集的标准差← 正确答案
  • C.两者的平均值
  • D.不需要标准化

答案:B。测试集必须复用训练集统计量(均值与标准差),否则会产生数据泄漏,让测试集错误地“提前知道”了自己的分布信息,导致评估结果虚高。这也是所有特征工程的通用原则。