讲解稿 · 第 02 章 第 05 节 · 矩阵分解¶
口播时长: 约 17-20 分钟|建议语速: 中速偏慢, 遇公式停两拍
开场钩子¶
先给你看一个真实场景。
你手上有一张 \(1000\times 1000\) 的灰度图, 一百万个像素点堆成一个方阵. 你想把它压缩到原来的 1/20, 但看起来跟原图几乎一样. 你打开 numpy, 三行代码, 出来了.
那三行代码里到底发生了什么? 它没有对像素挑挑拣拣, 也没有做傅立叶变换 — 它做了一件更神奇的事: 把这个方阵拆成三块, 然后扔掉不重要的那部分, 再把剩下的三块乘回来. 出来的图, 肉眼几乎看不出差别.
这就是矩阵分解在做的事. 一个复杂矩阵, 拆成两三个"性格更简单"的因子, 就像给整数做因式分解: 单看 \(12\) 你看不出什么, 写成 \(12 = 3\times 4\) 结构就跳出来了.
这一节, 我要把六种主要的分解方法排一排, 让你看清楚它们不是六个孤立招式, 而是一条主线: 都在想办法把矩阵变成三角形或对角形, 然后利用这个简单结构去干解方程、求逆、算幂、压缩数据这些原本很贵的事. 学完这节, 前面 Ch01 讲的基变换、这一章讲的线性变换, 会在这里彻底闭环.
准备好了吗? 上路.
复习昨日, 今日路线¶
上一节 (Ch02 §04) 我给你留了一句话: 每个矩阵都是一次线性变换. \(A\) 乘一个向量, 就是把这个向量按 \(A\) 的规则搬一次.
再往前一节, Ch01 §05 咱们讲了基变换矩阵 \(P\): 它的列, 是新基向量在旧基下的坐标, 一句口诀 — "\(P\) 的列是新基, \(P\) 把新坐标搬回旧描述". 关系是 \(\mathbf v_{旧} = P\,\mathbf v_{新}\), \(\mathbf v_{新} = P^{-1}\,\mathbf v_{旧}\).
今日路线一句话: 我们要把"变换"这个东西拆成好几步小变换的复合, 每一步都是一个三角矩阵、对角矩阵或者正交矩阵. 下一节 Ch03, 会把这些分解跟真实的算法效率、条件数联系起来.
核心概念一 · 分解的地基: 高斯消元¶
直觉: 你要解 \(A\mathbf x = \mathbf b\), 直接算 \(A^{-1}\) 又慢又不稳. 换个思路 — 把 \(A\) 一行一行变成三角形, 变成三角形以后, 最后一行只剩一个未知数, 直接读出; 倒数第二行只剩两个, 代回去 — 一路往上代回来. 这套动作叫回代 (back substitution).
定义: 允许三种行运算 — 换两行、某行乘非零标量、把某行的倍数加到另一行. 目标形式是行阶梯形 (REF): 每行首个非零元 (叫主元) 位于上一行主元右侧, 主元下方全是 0. 主元都变成 1、且主元所在列其他位置也是 0, 就叫简化行阶梯形 (RREF).
数字例子:
第一列消完了. 再一步 \(R_3 - 2R_2\), 第二列也消完, 三角形出现.
反例: 别忘了主元不能是 0. 如果消到某一步主元位置正好是 0, 必须先换行才能继续 — 这在 LU 分解里就是 \(A = PLU\) 里那个 \(P\) (置换矩阵, 别跟基变换的 \(P\) 混, 符号撞了) 的来源.
一句话: 高斯消元是所有分解方法的地基, 把矩阵化三角是它们共同的目的地.
核心概念二 · LU 分解 · 把消元变成两块拼图¶
直觉: 高斯消元每算一次只解一个 \(\mathbf b\). 但你在仿真里, 同一个 \(A\) 常常要配 1000 个不同的 \(\mathbf b\). 每次都消元一遍, 太浪费. LU 分解就是把消元做过的功记账下来: 一次分解, 万次复用.
定义: 把方阵 \(A\) 写成 \(A = LU\), 其中 \(L\) 是下三角 (对角线上方全 0), \(U\) 是上三角 (对角线下方全 0). 若消元过程中需要换行, 就写作 \(A = PLU\), 这里 \(P\) 是置换矩阵.
数字例子 (2×2 手算):
验证 \(LU\): 左上 \(1\cdot 2 = 2\)✓; 右上 \(1\cdot 3 = 3\)✓; 左下 \(2\cdot 2 = 4\)✓; 右下 \(2\cdot 3 + 1\cdot 1 = 7\)✓.
解法两步走: 要求 \(A\mathbf x = \mathbf b\), 令 \(\mathbf y = U\mathbf x\), 先解 \(L\mathbf y = \mathbf b\) (下三角, 从上往下前代), 再解 \(U\mathbf x = \mathbf y\) (上三角, 从下往上回代). 两次三角求解替换一次一般求解.
反例: 若 \(A_{11}=0\) 直接做 LU 会崩掉, 必须先换行, 这就是为什么工程上默认调 \(PLU\) 版本 (带部分主元选择).
一句话: LU 是"记账版"的高斯消元, 一次分解可以喂给任意多个右端.
核心概念三 · Cholesky · 对称正定的平方根¶
直觉: 如果你的矩阵是对称正定 — 比如所有协方差矩阵、所有 Gram 矩阵 — 你可以做得比 LU 更好. 类比: 正实数才开根号, 正定矩阵也有"平方根".
定义: 若 \(A\) 对称且正定, 则存在唯一下三角 \(L\), 使 \(A = LL^\top\).
数字例子:
比 LU 快约一倍 (少存一半元素), 数值稳定性有理论保证.
反例: 试着对 $$ \begin{pmatrix}1 & 2\ 2 & 1\end{pmatrix} $$ 做 Cholesky. 特征值 \(\lambda=3, -1\), 不是正定. 算到 \(L_{22} = \sqrt{1 - 2^2} = \sqrt{-3}\), 开根号出现负数, 算法崩. 崩这件事本身就是信息 — Cholesky 顺带是一个正定性检测器.
一句话: 对称正定专属, 更快、更稳、还能当体检.
⏸️ 暂停思考 · 第一次
我给你一个矩阵 $$ A = \begin{pmatrix} 9 & 3 \ 3 & 5 \end{pmatrix} $$. 试着心算一下它的 Cholesky 分解 \(L\) 长什么样. 提示: 左上元素是 \(\sqrt{9}\). 算不出来别着急听下去.
(答案: $$ L = \begin{pmatrix}3 & 0\ 1 & 2\end{pmatrix} $$.)
核心概念四 · 特征分解 · 找到矩阵的自然坐标系¶
这是这一节分量最重的概念, 也是 Ch01 §05 基变换的直接兑现. 我要把线性映射三条公理先放这里, 因为特征分解本质上就是"找到一组基, 让线性映射在这组基下变成对角矩阵".
线性映射三公理 (公理三件套, 每条: 名称 + 大白话 + 反例):
-
加性: \(T(\mathbf u + \mathbf v) = T(\mathbf u) + T(\mathbf v)\). 大白话: 先加再变, 跟先变再加, 结果一样. 反例: \(T(\mathbf v) = \mathbf v + (1,0)\) (平移), \(T((0,0)+(0,0)) = (1,0)\), 但 \(T((0,0)) + T((0,0)) = (2, 0)\), 不相等 — 所以平移不是线性映射.
-
齐次: \(T(c\mathbf v) = c\,T(\mathbf v)\). 大白话: 缩放和变换换序不影响结果. 反例: \(T(\mathbf v) = \|\mathbf v\|\mathbf v\) (按模长再放缩自己), \(T(2\mathbf v) = 2\|\mathbf v\|\cdot 2\mathbf v = 4\|\mathbf v\|\mathbf v\), 但 \(2T(\mathbf v) = 2\|\mathbf v\|\mathbf v\), 差了两倍 — 所以这个函数不是线性的.
-
零映射保持: \(T(\mathbf 0) = \mathbf 0\). 大白话: 原点不能被搬走. 反例: 任何仿射平移都违反这条, 上面的 \(T(\mathbf v) = \mathbf v + (1, 0)\) 把原点搬到 \((1, 0)\), 就废了.
这三条其实前两条推得出第三条, 但我们把第三条单列, 因为它是最快的排除标志 — 一眼看有没有平移, 就能筛掉一半假冒的"线性变换".
好, 三公理放下. 现在讲特征分解.
直觉: 大部分向量被 \(A\) 一乘, 方向都变了. 但有些特殊方向, \(A\) 只把它拉长或压缩, 不转向. 这些方向叫特征向量 (eigenvector), 那个缩放因子叫特征值 (eigenvalue).
符号首现四件套:
-
\(\lambda\) — 特征值 (eigenvalue): 满足 \(A\mathbf x = \lambda \mathbf x\) 的标量. 例: $$ A = \begin{pmatrix}3 & 1\ 0 & 2\end{pmatrix} $$, \(\mathbf x = (1, 0)^\top\) 是 \(\lambda = 3\) 的特征向量.
-
\(D\) — 对角矩阵 (diagonal matrix): 只有对角线上有非零元的方阵. 例: $$ D = \begin{pmatrix}3 & 0\ 0 & 2\end{pmatrix} $$.
定义: 若 \(A\) 有 \(n\) 个线性无关的特征向量, 把它们按列拼成矩阵 \(P\), 把对应特征值按序放进对角矩阵 \(D\), 则
这叫对角化. 这里的 \(P\), 列就是特征向量 — 你听出来了吗? 这跟 Ch01 §05 说的 "\(P\) 的列 = 新基向量在旧基下的坐标" 一模一样. 特征向量组成的这组新基, 有个专门的名字, 叫特征基 (eigenbasis). 在特征基下, 变换 \(A\) 就变成对角矩阵, 沿每个特征向量方向独立缩放, 干净利落.
为什么这样写? 换一个视角: 把 \(\tilde A = D\) 看作 \(A\) 在新基 (特征基) 下的矩阵, 按 Ch01 §05 的相似变换约定 \(\tilde A = P^{-1} A P\), 反解就是 \(A = P \tilde A P^{-1} = P D P^{-1}\). 完全对上.
数字锚点 (2×2 手算走一遍, 顺便补 Ch01 遗留的 \(P^{-1}\) 计算断层):
取 $$ A = \begin{pmatrix}3 & 1\ 0 & 2\end{pmatrix} $$. 特征多项式 \(\det(A - \lambda I) = (3-\lambda)(2-\lambda) = 0\), 特征值 \(\lambda_1 = 3, \lambda_2 = 2\).
\(\lambda_1 = 3\): 解 \((A - 3I)\mathbf x = \mathbf 0\), 得 \(\mathbf x_1 = (1, 0)^\top\). \(\lambda_2 = 2\): 解 \((A - 2I)\mathbf x = \mathbf 0\), 得 \(\mathbf x_2 = (-1, 1)^\top\).
拼起来:
\(P^{-1}\) 怎么算 (Ch01 遗留断层, 这里补上): 2×2 矩阵 $$ \begin{pmatrix}a & b\ c & d\end{pmatrix} $$, 逆等于 $$ \frac{1}{ad-bc}\begin{pmatrix}d & -b\ -c & a\end{pmatrix} $$ — 对角互换、副对角变号、除以行列式. 套进来: \(\det P = 1\), 所以
验证 \(PDP^{-1}\): $$ DP^{-1} = \begin{pmatrix}3 & 3\ 0 & 2\end{pmatrix} $$, 再乘 \(P\) 得 $$ \begin{pmatrix}3 & 1\ 0 & 2\end{pmatrix} $$✓. (3×3 及以上的 \(P^{-1}\) 靠公式手算就痛苦了, 用高斯消元或 LU, 我们下一章 Ch03 详讲.)
为什么值得: 想算 \(A^{100}\)? 直接自乘一百次太贵. 但 \(A^{100} = PD^{100}P^{-1}\), 而 \(D^{100}\) 就是把每个对角元素独立乘方. \(O(n^4)\) 一下降到 \(O(n)\).
反例: 不是每个方阵都能对角化. $$ A = \begin{pmatrix}1 & 1\ 0 & 1\end{pmatrix} $$ 只有一个线性无关的特征向量 \((1,0)^\top\), 对应重根 \(\lambda = 1\), 凑不出 2 个独立方向, 没法对角化. 这种时候要靠 Jordan 标准形或 Schur 分解 (⭐ 进阶).
几条要背的性质: 迹 \(= \sum \lambda_i\); 行列式 \(= \prod \lambda_i\); 对称矩阵特征值全实、特征向量两两正交 — 这条就是谱定理, PCA 的理论根基.
一句话: 对角化 = 找到线性变换的自然坐标系, 让复杂运算退化成独立缩放.
⏸️ 暂停思考 · 第二次
我给你 $$ A = \begin{pmatrix}2 & 0\ 0 & 3\end{pmatrix} $$, 直接问你: 它的特征值、特征向量是什么? \(A^{100}\) 是多少? 这题送分, 但你能一秒答出来, 说明你抓到了特征分解的精髓.
核心概念五 · QR 分解 · 分离方向和缩放¶
直觉: 特征分解只对方阵可做, 且要求可对角化. 那非方阵怎么办? 先看一个更朴素的分解 — QR.
定义: 任意矩阵 \(A\) 可写成 \(A = QR\), 其中 \(Q\) 列向量单位正交 (即 \(Q^\top Q = I\)), \(R\) 上三角. 直观分工: \(Q\) 装"方向", \(R\) 装"缩放和混合".
怎么构造: 用 Gram-Schmidt 过程逐列造 \(Q\) — 第一列归一化; 第二列减去它在第一列方向上的投影 (逼它跟第一列垂直), 再归一化; 一路做下去. 每一步都是"投影 + 减去 + 归一".
数字例子 (2×2 极简):
第一列 \((1,0)\) 已经是单位向量; 第二列 \((1,1)\) 减掉在 \((1,0)\) 上的投影 \((1,0)\) 得到 \((0,1)\), 已经是单位. 所以 \(Q\) 就是单位阵, \(R\) 上三角.
用途两件: 一是特征值 QR 算法的引擎 — 反复 \(A = QR\) 再合成 \(RQ\), 迭代下去矩阵会收敛为三角, 对角线读出所有特征值; 二是最小二乘: 当 \(A\mathbf x = \mathbf b\) 无精确解 (方程比未知数多), QR 给出的 \(\hat{\mathbf x} = R^{-1}Q^\top \mathbf b\) 就是最佳近似解.
一句话: QR = 把矩阵的方向骨架和缩放骨架分离出来.
核心概念六 · SVD · 万能钥匙¶
来了, 最通用的一个 — 奇异值分解 SVD. 我之前说了, 特征分解只管方阵, 而且要求可对角化. SVD 对任何矩阵都能做, 长方形、方形、满秩、亏秩, 通吃.
直觉: 任何一次线性变换, 都可以拆成"转一下 → 沿正交轴各自缩放一下 → 再转一下". 圆最后被拉成椭圆.
定义: 对任意 \(m \times n\) 矩阵 \(A\),
- \(V^\top\) (\(n \times n\), 正交): 先旋转输入
- \(\Sigma\) (\(m \times n\), 对角): 沿正交轴缩放, 对角元 \(\sigma_1 \ge \sigma_2 \ge \dots \ge 0\) 称为奇异值
- \(U\) (\(m \times m\), 正交): 再旋转输出
符号首现: \(\sigma_i\) — 奇异值: \(A^\top A\) 特征值的平方根. 例: $$ A = \begin{pmatrix}3 & 0\ 0 & 2\end{pmatrix} $$, \(\sigma_1 = 3, \sigma_2 = 2\).
几何解读: 奇异值揭示每个方向的"重要性". \(A\) 的秩 = 非零奇异值的个数. 大奇异值对应主要能量方向, 小奇异值往往就是噪声.
核心应用一 · 低秩逼近: 保留最大的 \(k\) 个奇异值, 其余置零, 得到的 \(A_k\) 是 \(A\) 在 Frobenius 范数下最佳的秩- \(k\) 逼近 (Eckart-Young 定理). 一张 \(1000\times 1000\) 图, \(k = 50\) 常常肉眼看不出差异, 存储需求从 \(10^6\) 降到 \(2 \cdot 50 \cdot 1000 + 50 \approx 10^5\), 压 20 倍. 开场那个魔术就是这么变的.
核心应用二 · 伪逆: \(A^+ = V \Sigma^+ U^\top\), 其中 \(\Sigma^+\) 把非零奇异值取倒数. 这解决了非方阵/亏秩矩阵求逆的痛点, 也是最小二乘的标准解形式.
一句话: SVD 是分解界的万能钥匙 — 任何矩阵都能拆成"旋转-缩放-旋转".
一个走完全程的例子 · 从数据到 PCA¶
咱们把这一节所有概念串一遍. 场景: 主成分分析 PCA.
假设你有一个数据矩阵 \(X\) (\(n\) 行样本, \(d\) 列特征), 目标是找出方差最大的几个方向.
第 1 步 · 标准化: 每列减去均值除以标准差. 别偷懒 — 用公里做单位的特征会把厘米做单位的特征盖死.
第 2 步 · 造协方差矩阵: \(C = \frac{1}{n-1}X^\top X\) (\(d \times d\), 对称半正定). 这是一个 Gram 矩阵, 天生长得像 Cholesky 能对付的对象.
第 3 步 · 特征分解 \(C = P D P^{-1}\): 因为 \(C\) 对称, 谱定理告诉我们 \(P\) 甚至是正交矩阵, 满足 \(P^{-1} = P^\top\) — 逆矩阵直接转置就有, 免算. 这也是为什么工程上做 PCA 从不手算 \(P^{-1}\).
第 4 步 · 挑出前 \(k\) 大特征值对应的 \(k\) 个特征向量, 这些就是主成分. 把 \(X\) 乘 \(P_k\) (前 \(k\) 列组成的子矩阵) 就投影到低维.
或者一步到位 · 直接 SVD: \(X = U \Sigma V^\top\), \(V\) 的前 \(k\) 列就是前 \(k\) 个主成分, 奇异值平方 \(/n-1\) 就是协方差矩阵的特征值. 一步替代前面四步.
举个 \(2\times 2\) 具体数: 协方差矩阵
特征值 \(\lambda_1 = 6, \lambda_2 = 2\). \(\lambda_1\) 对应 \((1,1)/\sqrt 2\), \(\lambda_2\) 对应 \((1,-1)/\sqrt 2\). 第一主成分方向就是 \((1,1)/\sqrt 2\), 数据大部分方差躺在这条对角线上. 想降到 1 维? 把数据点全投到 \((1,1)/\sqrt 2\) 这条线, 完成.
回到 Ch01 §05 说的那句话: 高维数据往往住在一个低维子空间里. PCA 就是把这个子空间具体算出来的方法. 你从 Ch01 埋下的"人脸照片其实只散布在 784 维空间里一个低得多的子空间上"这颗种子, 到今天在 SVD 这里发芽了.
易错点回头看¶
三条最容易翻车的地方:
易错一: 很多人以为 \(A = PDP^{-1}\) 里的 \(P\) 跟 Ch01 基变换的 \(P\) 是两回事, 其实是同一回事 — 因为特征向量在做的正是"新基", 特征基下的 \(\tilde A = D\), 按相似变换 \(\tilde A = P^{-1}AP\) 反解出来自然就是 \(A = PDP^{-1}\). 不要一看到新符号就慌, 结构是一致的.
易错二: 很多人以为 SVD 的 \(U\) 和 \(V\) 是同一组向量的两个名字, 其实是两组不同的正交基 — \(V\) 是 \(A^\top A\) 的特征向量组 (输入端的自然基), \(U\) 是 \(AA^\top\) 的特征向量组 (输出端的自然基). 当 \(A\) 是方阵且对称时, \(U = V\) 才成立, 一般情况下必须分开.
易错三: 很多人以为对称正定矩阵一定能做 Cholesky, 因此写代码时不加保护. 其实数值上只要有小小的浮点误差把某个应当为正的对角元推到 \(-10^{-15}\), Cholesky 就崩. 因为它在开根号时对负数零容忍. 生产代码里要么加正则化 \(C + \varepsilon I\), 要么改用 LDLᵀ 变种.
与下节的钩子¶
这一节我们把矩阵拆开了六种. 下一章 Ch03 会问一个更狠的问题: 这些分解算起来到底多贵? \(3\times 3\) 的 \(P^{-1}\) 你现在还能咬牙手算, \(1000\times 1000\) 的呢? 一次特征分解到底扫多少次浮点? 什么时候用迭代算法 (幂迭代、Lanczos、Arnoldi) 比直接分解划算? 什么叫条件数, 为什么它决定了你今晚会不会被数值精度 bug 吵醒?
带着这些问题, 咱们下一章 · 数值方法, 见.