想象你被派到一个陌生城市做交通规划。你手里有全市居民的通勤轨迹——每个人每天从哪出发、去哪、走哪条路。数据多到看不过来,但你真正关心的只有一件事:这个城市的主干道到底在哪?是东西向还是南北向?只要抓住这几条主干道,你就能理解整个城市的出行格局。 PCA 干的就是这件事:在纷繁的数据里,找到那个“方差最大”的方向——最能把数据摊开、最能代表整体结构的方向。而 SVD 则像一套给路网做“体检”的工具:它把整张通勤矩阵拆成“出行模式 × 流量大小 × 道路骨架”三块,让你只看最重要的几条路就能重建出接近原样的地图。更妙的是,随机 SVD 相当于“随机抽查几条街道”,就能极快地估算出主干道方向——这正是大矩阵降维加速的秘诀。 这篇文章,我们就沿着这条“城市主干道”把 SVD 与 PCA 的关系一次讲透:从等价性、截断降维,到随机加速,再到实战选型与面试题。

岗位关联

掌握“数据主干道”的寻找术,是数据降维、推荐系统和图像压缩岗位的必备技能,也是面试高频考点,学完即可用 SVD 实现 PCA 降维。

目录
  1. 可视化演示
  2. PCA降维原理
  3. 协方差特征分解
  4. SVD等价性
  5. 截断SVD降维
  6. 随机SVD加速
  7. 稳定性计算量对比
  8. 实战应用选型
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示SVD与PCA等价性、截断SVD降维过程与奇异值衰减曲线,可视化数据投影到主成分的维度压缩。

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

SVD降维投影过程 数据点投影到前k个主成分方向,保留最大方差 X_k=U_kΣ_kV_k^T 截断SVD在Frobenius范数下最优低秩近似

PCA降维原理

假设你手里有一张城市通勤地图,上千条线路密密麻麻。要快速抓住全貌,你不会逐条研究每条小路,而是找出少数几条“主干道”——它们承载了绝大多数人流,方向最能代表城市的骨架。PCA 做的正是这件事:在数据里找到最能摊开全貌的那条线。

计算机里,每条通勤记录是一个向量,所有记录构成数据矩阵 X。数据的“人流分散程度”在数学上叫方差。“主干道”就是这样一个方向 w:把数据投影到 w 上之后,投影点的方差最大。

要最大化这个量,还要约束 w 是单位向量,因为方向不随长度变化。解这个约束优化问题,答案就是协方差矩阵 C 的最大特征值对应的特征向量——第一条主干道就此诞生。

找到的第一个 w 就是城市第一条“主干道”——第一主成分。找到它之后,在垂直方向再找第二条,依此类推,城市骨架便一步步勾勒出来。

max⁡∥w∥=1 1n∑i=1n(xi⊤w)2=max⁡∥w∥=1 w⊤Cw\displaystyle \max_{\|\boldsymbol{w}\|=1}\ \frac{1}{n}\sum_{i=1}^{n}(\boldsymbol{x}_i^{\top}\boldsymbol{w})^{2}=\max_{\|\boldsymbol{w}\|=1}\ \boldsymbol{w}^{\top}\boldsymbol{C}\boldsymbol{w}
这个式子说明:找“人流最宽的方向”,等价于让单位向量 w 与协方差矩阵 C 形成的二次型 wᵀCw 最大。
  1. 投影坐标每个样本点 x_i 在方向 w 上的坐标是内积 w·x_i,相当于把点“压”到主干道的刻度上。
    zi=xi⊤wz_i = \boldsymbol{x}_i^{\top}\boldsymbol{w}
  2. 投影方差对所有投影坐标求平方平均,即数据中心化后的方差;方差的本质是“人流在主干道上铺开的宽度”。
    1n∑i=1nzi2=w⊤Cw\frac{1}{n}\sum_{i=1}^{n}z_i^{2} = \boldsymbol{w}^{\top}\boldsymbol{C}\boldsymbol{w}
  3. 单位约束加上 ||w|| = 1 去掉方向长短的无关自由度,保证只在“朝向”上比较,不因长度偷分。
    ∥w∥=1\|\boldsymbol{w}\| = 1

协方差特征分解

主干道不会独立存在:如果南北向的主干道堵车,东西向可能也跟着堵。要完整理解路网,你需要一张“路与路之间如何联动”的地图——协方差矩阵就是这张地图。

把 n 条通勤记录整理成矩阵 X(每行一个样本),先对每列减去均值做中心化,再计算 XᵀX/(n−1),就得到 d×d 的协方差矩阵 C。C 的第 i 行第 j 列刻画道路 i 与道路 j 的联动强弱,对角线则是每条路自身的波动幅度。

特征分解把 C 写成 QΛQᵀ。Q 的每一列是一个特征向量(方向),Λ 对角线上的元素是特征值(该方向上的方差大小)。把特征值从大到小排序,对应的特征向量就是第一、第二……主成分方向,城市骨架由此完整列出。

拿到这张“相关性地图”的特征分解,你就拥有了城市主干道的完整目录。但直接走这条路线有个隐患:先平方数据再做分解,数值上容易“失真”——这就是下一节 SVD 登场的原因。

C=1n−1X⊤X,C=QΛQ⊤,λ1≥λ2≥⋯≥λd\displaystyle \boldsymbol{C}=\frac{1}{n-1}\boldsymbol{X}^{\top}\boldsymbol{X},\qquad \boldsymbol{C}=\boldsymbol{Q}\boldsymbol{\Lambda}\boldsymbol{Q}^{\top},\qquad \lambda_{1}\ge\lambda_{2}\ge\cdots\ge\lambda_{d}
协方差矩阵的特征分解,就是给“城市路网相关性地图”做一次主方向拆解:Q 是方向、Λ 是各方向的重要程度。
  1. 数据中心化先让每列均值为 0,否则协方差会被“市中心”的绝对位置污染;我们要看“波动”而不是“位置”。
    X←X−xˉ\boldsymbol{X} \leftarrow \boldsymbol{X} - \bar{\boldsymbol{x}}
  2. 协方差矩阵XᵀX 把所有样本的交叉联动累加后归一化,元素 (i,j) 表示第 i 条路与第 j 条路的联动强不强。
    C=1n−1X⊤X\boldsymbol{C} = \frac{1}{n-1}\boldsymbol{X}^{\top}\boldsymbol{X}
  3. 特征分解Q 的列给出方向(路网骨架),Λ 的对角元给出每个方向上的“人流宽度”,降序排列后逐条取用。
    Cqi=λiqi,λ1≥λ2≥⋯\boldsymbol{C}\boldsymbol{q}_{i}=\lambda_{i}\boldsymbol{q}_{i},\quad \lambda_{1}\ge\lambda_{2}\ge\cdots

SVD等价性

同样是研究城市路网,你可以用“相关性地图”(协方差矩阵),也可以直接看“每条通勤记录本身”。SVD 就是直接拆解原始记录的方案:它把整个通勤矩阵拆成三块积木。

对中心化后的数据矩阵 X(n×d)做 SVD:X = UΣVᵀ。U 的列是“出行模式的空间”,V 的列是“道路骨架方向”,Σ 的对角元是奇异值,刻画每个方向的流量大小。把 XᵀX 代进去,会得到一个漂亮的结论。

XᵀX = (UΣVᵀ)ᵀ(UΣVᵀ) = VΣ²Vᵀ。这说明:X 的奇异值平方恰好是 XᵀX 的特征值(λ_i = σ_i²),右奇异向量 V 的列恰好是 XᵀX 的特征向量。换句话说,协方差矩阵的特征分解就是 SVD 的“平方视角”——数学上等价,但数值上 SVD 更稳,因为不用先把数据平方一次。

同一座城市,协方差特征分解像“平方后的地图”,SVD 像“原始测绘数据”。结论一致,但原始数据少了一次平方误差,更稳更准,这也是工程上常用 SVD 实现 PCA 的原因。

X=UΣV⊤⟹X⊤X=VΣ2V⊤,λi=σi2\displaystyle \boldsymbol{X}=\boldsymbol{U}\boldsymbol{\Sigma}\boldsymbol{V}^{\top}\quad\Longrightarrow\quad \boldsymbol{X}^{\top}\boldsymbol{X}=\boldsymbol{V}\boldsymbol{\Sigma}^{2}\boldsymbol{V}^{\top},\quad \lambda_{i}=\sigma_{i}^{2}
这是全文最核心的桥:特征分解与 SVD 不是两套方法,而是同一副城市骨架的两种观察方式。
  1. SVD 分解任何 n×d 矩阵都能拆成左奇异向量 U、奇异值 Σ、右奇异向量 Vᵀ 三块,U 与 V 的列各自正交。
    X=UΣV⊤\boldsymbol{X}=\boldsymbol{U}\boldsymbol{\Sigma}\boldsymbol{V}^{\top}
  2. 代入转置相乘把 XᵀX 展开,利用 UᵀU = I 消去中间项,剩下 VΣ²Vᵀ。
    X⊤X=(VΣU⊤)(UΣV⊤)=VΣ2V⊤\boldsymbol{X}^{\top}\boldsymbol{X}=(\boldsymbol{V}\boldsymbol{\Sigma}\boldsymbol{U}^{\top})(\boldsymbol{U}\boldsymbol{\Sigma}\boldsymbol{V}^{\top})=\boldsymbol{V}\boldsymbol{\Sigma}^{2}\boldsymbol{V}^{\top}
  3. 特征值桥接左右对照,XᵀX 的特征值就是 σ_i²,特征向量就是 V 的各列,二者指向同一副骨架。
    λi=σi2\lambda_{i}=\sigma_{i}^{2}

截断SVD降维

城市不可能把所有小巷都纳入主干规划。交通规划的常规操作是:从所有道路里挑出流量最大的前 k 条“快速路”,升级为主干网,其余小巷忽略——城市骨架照样清晰。

截断 SVD 就是这个操作:只保留前 k 个最大的奇异值和对应的奇异向量,得到低秩矩阵 X_k = U_k Σ_k V_kᵀ。投影坐标 Z = X V_k 就是降维后的主成分得分,任何新样本都能用这套“快速路网”换上低维坐标。

矩阵可以写成 r 个“秩一外积”之和:X = Σ σ_i u_i v_iᵀ。截断到 k 项后,丢掉的是 σ_{k+1}…σ_r 对应的“小巷”。Eckart–Young 定理保证:在所有秩不超过 k 的矩阵里,X_k 的 Frobenius 重构误差最小,误差恰好等于被丢掉奇异值的平方和开根号。

快速路留多少条,取决于你能容忍多少“地图失真”。实际使用时常看方差保留率——前 k 个奇异值平方和占总平方和的比例——来决定 k,这就是压缩与信息的权衡。

Xk=∑i=1kσi uivi⊤,∥X−Xk∥F=∑i=k+1rσi2\displaystyle \boldsymbol{X}_k=\sum_{i=1}^{k}\sigma_i\,\boldsymbol{u}_i\boldsymbol{v}_i^{\top},\qquad \|\boldsymbol{X}-\boldsymbol{X}_k\|_F=\sqrt{\sum_{i=k+1}^{r}\sigma_i^{2}}
截断 SVD 告诉我们:留几条快速路、丢几条小巷,有一个精确的“失真账单”,可以提前算出来。
  1. 外积展开每个 σ_i u_i v_iᵀ 都是一层“道路图层”,σ_i 越大图层越重要,总图由这些图层叠加而成。
    X=∑i=1rσi uivi⊤\boldsymbol{X}=\sum_{i=1}^{r}\sigma_i\,\boldsymbol{u}_i\boldsymbol{v}_i^{\top}
  2. 截断保留只叠前 k 层得到 X_k;它仍是完整的 n×d 矩阵,但摸起来“更粗糙”,丢掉了细节小巷。
    Xk=∑i=1kσi uivi⊤\boldsymbol{X}_k=\sum_{i=1}^{k}\sigma_i\,\boldsymbol{u}_i\boldsymbol{v}_i^{\top}
  3. 重构误差Frobenius 范数衡量“重建地图与真实地图的差距”,它等于被丢弃奇异值的平方和开根号,是判断留几条快速路的标尺。
    ∥X−Xk∥F=∑i=k+1rσi2\|\boldsymbol{X}-\boldsymbol{X}_k\|_F=\sqrt{\sum_{i=k+1}^{r}\sigma_i^{2}}

随机SVD加速

如果城市有几十万条路,完整测绘耗时巨大。聪明交通局的做法是:随机抽查一小批街道的流量,先粗略判断主干道的方向,再沿这个方向精确复测——几轮下来,主干道就清清楚楚了。

随机 SVD 正是这套思路。先用 d×ℓ 的高斯随机矩阵 Ω(ℓ = k + p,p 是过采样列数)和 X 相乘得到草图 Y = XΩ,Y 的列就像“抽查的街道”。对 Y 做 QR 分解得到正交基 Q,Q 张成的子空间大概率覆盖了主要奇异方向。

把 X 投影到 Q 的低维子空间上得到小矩阵 B = QᵀX(只有几十到几百行/列),对它做完整 SVD 代价极小,再回代 U ≈ Q U_B。想要更高精度,可先做 q 次幂迭代:用 (XXᵀ)ᵍ XΩ 代替 XΩ,相当于“沿主干道多复查几次”,让次要方向被进一步压制。

抽查带来了惊人的加速:当矩阵达到 10 万行、几千列时,随机 SVD 可能比完整 SVD 快一个数量级,而精度损失往往在可接受范围——这正是“大数据降维加速”的核心武器。

Y=XΩ,Q=qr(Y),B=Q⊤X≈U~Σ~V~⊤,X≈QB\displaystyle \boldsymbol{Y}=\boldsymbol{X}\boldsymbol{\Omega},\qquad \boldsymbol{Q}=\mathrm{qr}(\boldsymbol{Y}),\qquad \boldsymbol{B}=\boldsymbol{Q}^{\top}\boldsymbol{X}\approx \tilde{\boldsymbol{U}}\tilde{\boldsymbol{\Sigma}}\tilde{\boldsymbol{V}}^{\top},\qquad \boldsymbol{X}\approx\boldsymbol{Q}\boldsymbol{B}
随机 SVD 的精髓:先用随机投影把大矩阵“折叠”成小矩阵,在小矩阵上精算,再还原到大空间。
  1. 随机草图用高斯随机矩阵 Ω 和 X 相乘,把信息压缩到低维空间;ℓ = k + p 多采几列可提高覆盖率。
    Y=XΩ,ℓ=k+p\boldsymbol{Y}=\boldsymbol{X}\boldsymbol{\Omega},\quad \ell=k+p
  2. 正交化对 Y 做 QR 分解得到列正交的 Q,Q 的列张成一个靠谱的低维子空间,近似“主干道候选方向”。
    Y=QR\boldsymbol{Y}=\boldsymbol{Q}\boldsymbol{R}
  3. 小矩阵消化在低维空间里算 B = QᵀX 再 SVD,计算量从大矩阵级别降到小矩阵级别。
    B=Q⊤X\boldsymbol{B}=\boldsymbol{Q}^{\top}\boldsymbol{X}
  4. 回代还原最后用 U ≈ Q U_B 把左奇异向量“搬回”原空间,全程只在大矩阵上做了两次矩阵乘法。
    U≈QUB\boldsymbol{U}\approx\boldsymbol{Q}\boldsymbol{U}_B

稳定性计算量对比

修主干道有三套方案:A 案把全市每条路都测量三遍(特征分解 + 构造 XᵀX),B 案直接测绘原始记录(完整 SVD),C 案先抽查再精修(随机 SVD)。方案 A 精度未必更高,成本却更高。

数值上最大的坑是“平方灾难”:构造 XᵀX 时把奇异值平方,条件数从 κ(X) 变成 κ(X)²。条件数是“误差放大的倍数”,它一平方,小奇异值对应的方向精度会急剧劣化——这也是为什么工程上用 SVD 而非特征分解。

计算量方面:显式求 XᵀX 要 O(nd²),特征分解 O(d³);完整 SVD 对 n×d 矩阵是 O(nd²),但直接作用于 X 不产生平方误差;截断 SVD 只要 O(ndk);随机 SVD 约 O(ndℓ + ℓ²d),ℓ 远小于 d 时最快,且稀疏矩阵还能吃满稀疏乘法的红利。

方案 A 看似最“正统”,却最伤数值;工程上默认用完整/截断 SVD 替代协方差特征分解,只有矩阵小到可以挥霍时才用特征分解——这是省钱又安全的修路哲学。

κ(X⊤X)=(σmax⁡σmin⁡)2=κ(X)2,TSVD≈O(nd2)\displaystyle \kappa(\boldsymbol{X}^{\top}\boldsymbol{X})=\left(\frac{\sigma_{\max}}{\sigma_{\min}}\right)^{2}=\kappa(\boldsymbol{X})^{2},\qquad T_{\mathrm{SVD}}\approx O(nd^{2})
条件数平方放大是“构造 XᵀX”方案的原罪;截断与随机 SVD 用更少的乘法和更稳的数值换来了双重优势。
  1. 条件数定义最大与最小奇异值之比,衡量矩阵“多敏感”;比值越大,微小测量误差被放大得越狠。
    κ(X)=σmax⁡σmin⁡\kappa(\boldsymbol{X})=\frac{\sigma_{\max}}{\sigma_{\min}}
  2. 平方放大构造 XᵀX 后条件数变成平方——原本 10 的敏感度变成 100,数值误差被平方放大。
    κ(X⊤X)=κ(X)2\kappa(\boldsymbol{X}^{\top}\boldsymbol{X})=\kappa(\boldsymbol{X})^{2}
  3. 复杂度参照完整 SVD 约 O(nd²),截断 SVD 只乘 k 份约 O(ndk),随机 SVD 用 ℓ=k+p 再省一截,选多保贵。
    TSVD≈O(nd2)≫Ttrunc≈O(ndk)T_{\mathrm{SVD}}\approx O(nd^{2})\gg T_{\mathrm{trunc}}\approx O(ndk)

实战应用选型

小县城几十条路,全量测绘即可;特大城市千万条路,必须抽查法;而景区只要画好 k 条观景主干道,就能让你不走回头路。数据场景不同,选型天差地别。

选型三问:数据规模多大(n、d)?要前 k 个方向还是全部?矩阵稠密还是稀疏?小矩阵(几百×几百)直接用 np.linalg.svd 全量分解;中等矩阵用截断 SVD;超大矩阵(d 或 n 上万)用随机 SVD。

典型场景里:图像压缩把 512×512 图像做截断 SVD,只存 U_k、Σ_k、V_kᵀ,k 取 30~50 时压缩率可达 10~20 倍且肉眼难辨差异;推荐系统把用户-物品评分矩阵做随机 SVD 得到隐向量,等价于矩阵分解;人脸识别中的“特征脸”直接用 PCA 的 V 列构成“基础脸”,任何脸都是它们的线性组合。选 k 统一看方差保留率。

主干道不一定越多越好,够承载九成流量即可。选型口诀:小矩阵全量 SVD,中矩阵截断 SVD,大矩阵随机 SVD——三招吃遍降维场景。

Rk=∑i=1kσi2∑i=1rσi2≥0.9 ⇒ k=arg⁡min⁡k{Rk≥0.9}\displaystyle R_{k}=\frac{\sum_{i=1}^{k}\sigma_{i}^{2}}{\sum_{i=1}^{r}\sigma_{i}^{2}}\ge 0.9\ \Rightarrow\ k=\arg\min_{k}\{R_{k}\ge 0.9\}
主干道不贪多,够承载九成流量即可。方差保留率是决定 k 的通用标尺。
  1. 方差保留率前 k 个奇异值平方和占全部平方和的比例,相当于“主干网承载了全市百分之多少的流量”。
    Rk=∑i=1kσi2∑i=1rσi2R_{k}=\frac{\sum_{i=1}^{k}\sigma_{i}^{2}}{\sum_{i=1}^{r}\sigma_{i}^{2}}
  2. 阈值选择通常要求 R_k ≥ 90%,取满足条件的最小 k——流量覆盖够用就好,不贪多。
    k=arg⁡min⁡k{Rk≥0.9}k=\arg\min_{k}\{R_{k}\ge 0.9\}
  3. 应用落点图像压缩、推荐隐向量、特征脸都套同一个流程:SVD → 取前 k 个 → 投影或重构。
    Z=XVk\boldsymbol{Z}=\boldsymbol{X}\boldsymbol{V}_{k}

AI 应用场景

图像压缩:把照片当“城市地图”修剪

阶段:数据预处理 / 特征压缩

解决的问题:高分辨率图像存储和传输成本高,传统做法按像素块硬压缩容易产生明显失真。数学上,灰度图就是一个数字矩阵,把它交给截断 SVD,只保留前 k 条“快速路图层”,城市骨架清晰,小巷全部丢弃。

具体案例:一张 512×512 的人像灰度图,做截断 SVD 取 k=40,存储量从 512×512=26 万个数降到 512×40 + 40 + 40×512 约 4 万个数,压缩 6 倍以上,人眼几乎看不出差别。工程上通常配合奇异值衰减曲线快速定 k。

推荐系统隐语义:主干道客流预测小巷流量

阶段:特征工程 / 模型输入

解决的问题:用户-物品评分矩阵动辄几十万行、几万列,稀疏度超 99%,直接计算用户相似度又慢又占内存。随机 SVD 把矩阵分解成“用户隐向量 × 重要性 × 物品隐向量”,内积即可预测未评分项——就像用主干道的客流规律推测小巷的流量。

具体案例:某电商平台 10 万用户 × 5 万商品,评分稀疏度 99.2%,用随机 SVD(k=50,过采样 p=10)做矩阵分解,离线 AUC 提升 3%,训练时间从完整 SVD 的 40 分钟降到 3 分钟。

高维基因数据降维可视化

阶段:数据降维 / 可视化

解决的问题:基因表达矩阵常是 2 万基因 × 几百样本,维度极高且数值动态范围大。若先构造 2 万×2 万的协方差矩阵,内存与数值误差双双爆炸;直接用 SVD 对原始矩阵求主方向,再把样本投影到二维散点图,能直观展示样本聚类。

具体案例:某癌症转录组数据集 18000 基因 × 420 样本,用 PCA(底层 SVD)降到 2 维,正常组与肿瘤组在散点图上明显分成两簇,且比协方差特征分解快 5 倍、结果更稳。

Python 演示

python60 行
import timeimport numpy as np  def pca_via_svd(X, k):    Xc = X - X.mean(axis=0)    U, S, Vt = np.linalg.svd(Xc, full_matrices=False)    Z = Xc @ Vt[:k].T          # 主成分得分    Xk = Z @ Vt[:k]            # k 维重构    return Z, S[:k], Xk  def pca_via_eig(X, k):    Xc = X - X.mean(axis=0)    C = Xc.T @ Xc / (Xc.shape[0] - 1)    vals, vecs = np.linalg.eigh(C)    order = np.argsort(vals)[::-1][:k]    return Xc @ vecs[:, order]  def rsvd(X, k, p=5, q=1):    ell = k + p    Omega = np.random.randn(X.shape[1], ell)    Y = X @ Omega    for _ in range(q):        Y = X @ (X.T @ Y)      # 幂迭代压制小奇异方向    Q, _ = np.linalg.qr(Y)    B = Q.T @ X    Ub, S, Vt = np.linalg.svd(B, full_matrices=False)    return Q @ Ub[:, :k], S[:k], Vt[:k]  def main():    rng = np.random.default_rng(2024)    X = rng.standard_normal((5000, 600))     Z_svd, S, Xk = pca_via_svd(X, 5)    Z_eig = pca_via_eig(X, 5)    cos = abs(Z_svd[:, 0] @ Z_eig[:, 0])    cos /= np.linalg.norm(Z_svd[:, 0]) * np.linalg.norm(Z_eig[:, 0])    print("SVD 与特征分解得分余弦相似度:", round(cos, 6))    print("前5个奇异值:", np.round(S[:5], 2))     U, Sr, Vt_r = rsvd(X, 5)    err_trunc = np.linalg.norm(X - Xk, ord="fro")    err_rsvd = np.linalg.norm(X - (X @ Vt_r.T) @ Vt_r, ord="fro")    print("截断SVD 重构误差:", round(err_trunc, 4))    print("随机SVD 重构误差:", round(err_rsvd, 4))     t0 = time.time()    pca_via_svd(X, 5)    t_svd = time.time() - t0    t0 = time.time()    rsvd(X, 5)    t_rsvd = time.time() - t0    print("完整SVD 耗时 %.3fs, 随机SVD 耗时 %.3fs" % (t_svd, t_rsvd))  if __name__ == "__main__":    main()
目的:用一份 5000×600 的模拟数据,对比“SVD 实现 PCA”“协方差特征分解”“随机 SVD”三种路线的得分一致性、重构误差与运行耗时。
  1. U, S, Vt = np.linalg.svd(Xc, full_matrices=False)一步完成 SVD,得到左奇异向量、奇异值和右奇异向量。
  2. Z = Xc @ Vt[:k].T用 V 的前 k 列投影,算出主成分得分,即降维结果。
  3. C = Xc.T @ Xc / (Xc.shape[0] - 1)显式构造协方差矩阵,演示“平方视角”的路线。
  4. Y = X @ Omega随机投影:用高斯矩阵把大矩阵压成小草图。
  5. Y = X @ (X.T @ Y)幂迭代:沿主要方向“复查”,进一步压制小奇异方向。
  6. Q, _ = np.linalg.qr(Y)对草图做 QR 分解,得到靠谱的低维正交基。
  7. B = Q.T @ X把原矩阵投影到低维空间,得到小矩阵,后续 SVD 成本极低。

常见误区

误区“PCA 的标准流程就是先算协方差矩阵 C = XᵀX,再做特征分解;用 SVD 是偷懒的近似,不算正规 PCA。”

正解数学上两者完全等价:XᵀX = VΣ²Vᵀ,特征向量就是 V 的列。但工程上用 SVD 直接分解中心化的 X 更稳更快——构造 XᵀX 会把奇异值平方,条件数变成原来的平方,数值误差被放大。正规做法恰恰是 SVD 优先。

为何常见:教科书多先讲特征分解引入 PCA,SVD 版本放在后面,学习者先入为主,以为只有特征分解才算“正统”。

误区“SVD 分解出 X = UΣVᵀ,那么 U 就是下降维后的坐标,直接用 U 的前几列当特征就行。”

正解降维后的得分是样本在新坐标系里的坐标,等于 X V_k = U_k Σ_k;U 的列是左奇异向量,是 XXᵀ 的特征向量,描述的是“样本与方向的关系”,不是坐标本身。要得到特征必须用 V 去投影:Z = X V_k。

为何常见:SVD 输出三个矩阵,初学者最容易把第一个矩阵 U 当成“主成分”,混淆了变换矩阵与结果坐标。

误区“随机 SVD 名字里带'随机',应该是随机抽样数据,丢掉一部分行再分解,所以精度没有保证。”

正解随机 SVD 没有丢任何数据行,它只用随机矩阵做线性投影,所有样本都参与了计算。随机投影配合 QR 正交化和幂迭代,有理论保证能捕获主要奇异子空间;误差通常只比最优截断 SVD 高一点点,但耗时可能差一个数量级。

为何常见:'随机'二字容易让人联想到随机抽样或 dropout,忽略了它只是“换一种方式压缩维度、再精确还原”。

误区“截断 SVD 压缩矩阵,就是把元素里绝对值小的数清零,省存储。”

正解元素置零和低秩近似是两回事。截断 SVD 是整体丢弃“秩一图层”σ_i u_i v_iᵀ,丢层后矩阵的每个元素都会随之整体调整,但它保证了 Frobenius 范数下的最优重构误差——这是逐元素置零做不到的。

为何常见:“压缩 = 清零”是生活常识带来的直觉,但矩阵的低秩结构与元素大小没有直接关系。

面试题

Q1. 用 SVD 实现 PCA 时,样本在新空间中的主成分得分应如何计算?

单选题 · easy

  • A.取左奇异向量 U 的前 k 列作为得分
  • B.取右奇异向量 V 的前 k 列作为得分
  • C.用中心化数据乘 V 的前 k 列← 正确答案
  • D.用中心化数据乘 U 的前 k 列

答案:C。得分是样本在“主干道方向”上的坐标,方向由 V 的列给出,所以 Z = XV_k。A 的 U 列是 XXᵀ 的特征向量,描述样本与方向的关系而非坐标;B 的 V 列本身只是方向;D 维度对不上且含义错误。

Q2. 中心化后的数据矩阵 X,其 XᵀX 的特征值 λ 与奇异值 σ 的关系是?

单选题 · easy

  • A.λ = σ²← 正确答案
  • B.λ = √σ
  • C.λ = σ
  • D.λ = 1/σ

答案:A。由 XᵀX = VΣ²Vᵀ 可知特征值恰为奇异值平方。这就像“人流宽度”的平方视角:σ 是原始流量,λ 是流量平方后的量。B、C、D 都不满足这个代数推导。

Q3. Eckart–Young 定理说明截断 SVD 的最优性体现在哪里?

单选题 · mid

  • A.重构误差在所有低秩矩阵中最小← 正确答案
  • B.计算速度一定快于特征分解
  • C.保留的奇异值个数总是越少越好
  • D.重构结果一定等于原数据矩阵

答案:A。定理保证:在所有秩不超过 k 的矩阵里,截断 SVD 的 Frobenius 重构误差最小。B 是工程现象不是定理内容;C 违背信息损失权衡;D 与截断含义相反,k<r 时不会完全等于原矩阵。

Q4. 随机 SVD 算法的第一步通常做什么?

单选题 · mid

  • A.用高斯随机矩阵对数据做投影← 正确答案
  • B.把数据矩阵的每个元素求倒数
  • C.对数据矩阵做完整特征分解
  • D.把矩阵转置后再做一次乘法

答案:A。随机 SVD 先做 Y = XΩ 的随机投影,得到“抽查草图”。B 是数值变换但没有意义;C 是完整方法,违背随机加速初衷;D 单独转置不构成算法步骤。

Q5. 为什么工程上更倾向用 SVD 而不是协方差特征分解做 PCA?

单选题 · easy

  • A.因为奇异值分解只适用于稀疏矩阵
  • B.因为构造协方差矩阵会平方放大误差← 正确答案
  • C.因为特征分解在任何情况下都更慢
  • D.因为协方差矩阵多数情况不可对角化

答案:B。构造 XᵀX 会把条件数变成 κ(X)²,数值误差被平方放大;SVD 直接分解原始矩阵更稳。A 错误,SVD 对稠密矩阵同样适用;C 过于绝对;D 错误,实对称协方差矩阵必然可对角化。

Q6. 中心化矩阵 X 做 SVD 得 X=UΣVᵀ,关于 U 的列正确的是?

单选题 · mid

  • A.它们是数据矩阵 XᵀX 的特征向量
  • B.它们是矩阵 XXᵀ 的特征向量← 正确答案
  • C.它们是协方差矩阵的右奇异向量
  • D.它们是主成分得分矩阵的转置

答案:B。由 XXᵀ = UΣ²Uᵀ 可知 U 的列是 XXᵀ 的特征向量。A 中的特征向量是 V 的列;C 中协方差矩阵是 XᵀX(取 X 的右奇异向量);D 的得分是 XV_k = U_kΣ_k,不等于 U 本身。

Q7. 截断 SVD 重构误差 ||X−X_k||_F 的精确表达是?

单选题 · hard

  • A.被丢弃奇异值的平方和再开根号← 正确答案
  • B.被保留奇异值的平方和再开根号
  • C.最大奇异值减去最小奇异值的差
  • D.被保留的奇异值个数 k 的平方根

答案:A。Eckart–Young 定理给出误差 = √(Σ_{i=k+1}^r σ_i²),即“小巷图层”的总能量。B 是保留部分的能量而非误差;C 是奇异值跨度与误差无关;D 只与个数有关,显然不正确。

Q8. 随机 SVD 中提升低秩近似精度的常用技巧有哪些?

多选题 · hard

  • A.增加过采样列数以保证覆盖← 正确答案
  • B.做一到两次幂迭代压制小方向← 正确答案
  • C.把矩阵元素全部取绝对值参与计算
  • D.只保留最大的一个奇异值做近似

答案:AB。过采样(p 更大)提高随机投影覆盖完整子空间的概率;幂迭代 (XXᵀ)ᵍXΩ 让小奇异方向指数衰减,逼近最优。C 是破坏信息的非线性操作;D 等于 k=1 的暴力截断,不是精度技巧。

Q9. 关于 SVD 与 PCA 的等价性,下列说法正确的有?

多选题 · extreme

  • A.右奇异向量 V 的列就是主成分方向← 正确答案
  • B.奇异值平方等于 XᵀX 的特征值← 正确答案
  • C.直接做 SVD 数值上更稳定← 正确答案
  • D.左奇异向量 U 就是降维后的得分

答案:ABC。由 XᵀX = VΣ²Vᵀ,V 的列即主方向,σ² 即特征值,故 A、B 正确。构造 XᵀX 使条件数平方放大,因此 C 正确。D 错误:得分是 XV_k = U_kΣ_k,U 本身不是坐标。

Q10. 面对十万行、五千列的大矩阵做 PCA,合理做法有哪些?

多选题 · mid

  • A.用随机 SVD 加速分解过程← 正确答案
  • B.用截断 SVD 只求前 k 个方向← 正确答案
  • C.显式构造五千乘五千协方差矩阵
  • D.用完整 SVD 求出全部奇异向量

答案:AB。超大矩阵下,随机 SVD 与截断 SVD 都能显著降计算量且精度可控。C 的问题在于构造 XᵀX 既费时又放大数值误差,5000×5000 矩阵的特征分解代价高昂;D 求全部奇异向量在 10 万×5000 规模上几乎不可行。