简介:《线性代数的艺术》(The Art of Linear Algebra)是一本以图形化方式解读线性代数核心概念的PDF电子书,源自Kenji Hiranabe为Gilbert Strang《Linear Algebra for Everyone》制作的图解笔记,并配有中文翻译,适合希望摆脱抽象公式、通过直观图形理解矩阵运算的初学者和自学者。全书围绕“矩阵的四种视角”和“向量与矩阵的乘法”展开,系统梳理了CR、LU、QR、QΛQT与奇异值分解UΣVT等五大矩阵分解方法,揭示各分解背后的几何意义与实际用途——如CR揭示秩1结构,LU便于求解方程组,QR用于数值稳定计算,QΛQT对应特征值分解,SVD支撑降维与数据压缩。资源为单个PDF文件,体积仅1.43MB,内容紧凑且图文并茂,可直接用于系统复习或教学参考。目前已有572人学习浏览,是一份轻量而实用的线性代数可视化学习资料。
1. 从「背公式」到「看图」:The Art of Linear Algebra 中文版这份 PDF 究竟让谁少走三年弯路
很多人把《The Art of Linear Algebra》中文版当成一本画册,随手翻完就放下,然后继续回去背公式。这恰恰浪费了这份 PDF 最值钱的部分——它不是给你看热闹的,而是把线性代数里最容易劝退的抽象概念全部翻译成了可直视的几何画面:矩阵乘法变成了箭头的加权组合,四个子空间第一次有了形状,特征值变成了「拉伸方向」。它的中文版译名直白,内容却一点也不浅,适合三类人:被教材绕晕的初学者、天天调 numpy.linalg 却说不清底层逻辑的工程师,以及需要给学生讲清楚矩阵本质的人。这篇笔记我就按「它到底讲了什么 → 怎么自己动手复现 → 哪些地方容易翻车 → 怎么用到工程里」这个顺序给你讲透。
2. 这份 PDF 做了三件教科书没做的事:四个视角看矩阵乘法、把子空间画出来、让特征值有几何直觉
绝大多数教材教矩阵乘法只教一条路:左矩阵的行和右矩阵的列做点积。那当然是对的,但只对了一小部分。这份 PDF 最让人开窍的地方,就是把矩阵乘法拆成「能看到的动作」,而不是「能算出来的数」。这一章我们顺着它的三个关键设计往下讲,每一节都对应一个你现在就能动手验证的小实验。
2.1 矩阵乘法的四个视角:行列点积之外的三条捷径
先说明为什么点积视角不够。设 A 是 2×2 矩阵,x 是 2×1 列向量。点积视角把 Ax 看成两个方程、两个未知数的联立求解,你看到的是「数」。但一旦矩阵变大,行列点积会让你完全丧失方向感:算完了,结果是对的,却不知道这个结果在几何上意味着什么。这份 PDF 的做法是给矩阵乘法补了另外三个视角:列视角、行视角、列-行外积视角。
列视角是其中最常用的。把 x 的每个元素当成系数,把 A 的各列取出来做线性组合。换句话说,A 乘一个向量,本质上是「按权重把 A 的列向量加起来」——这就是为什么 Ax=b 有解要求 b 在 A 的列空间里。行视角对称地看:输出向量的每个分量,是对 A 的各行做加权组合。外积视角更极端,把整个矩阵拆成若干「列 × 行」的秩一矩阵之和,这也是后文理解奇异值分解压缩、低秩近似的起点。
动手验证很简单。取矩阵 A = [[1, 3], [2, 5]],x = [2, -1],分别从点积和列组合两个方向算一次:
- 点积算:第一行 1×2 + 3×(-1) = -1;第二行 2×2 + 5×(-1) = -1。
- 列组合算:2×(1, 2) + (-1)×(3, 5) = (2, 4) + (-3, -5) = (-1, -1)。
两边结果完全一致,但第二次你能看到,操作其实是「两步走的向量加法」:先沿第一列方向走 2 个单位,再沿第二列的反方向走 1 个单位,终点落在 (-1, -1)。这图一旦画出来,Ax 在你脑子里就再也不是黑匣子。
我一般会把三个视角做成一张对照表,方便讲给初学者,也方便自己在写代码前快速定位:
视角 | 一句话描述 | 直接解释的概念 列组合 | A 的列按 x 加权求和 | Ax=b 何时有解、列空间 行组合 | 输出分量是对 A 的行的加权和 | 行空间、行图像 秩一分解 | 矩阵可拆成列×行的累加 | 秩、奇异值分解、低秩近似
读这份 PDF 的时候,遇到任何公式,先在句子里找「这是哪个视角」。找不到视角的公式,八成是你还没理解它在描述什么,或者它根本没有几何意义。
2.2 四个基本子空间:一张图画对了,线性代数的地图就立起来了
子空间这一节是整份 PDF 最值钱的部分。很多教材把「行空间、列空间、零空间、左零空间」排成一张维数公式表,让你背 r + (n-r) = n。这份 PDF 不一样,它画的是「两两正交」的几何关系:行空间与零空间待在同一个坐标系里,互为正交补;列空间与左零空间待在另一个坐标系里,互为正交补。
这里最容易搞混、也是 PDF 特意用不同画布的原因:行空间和列空间不在同一个空间里。设 A 是 m 行 n 列,那么行空间是 n 维空间的子空间,列空间是 m 维空间的子空间。m 和 n 不相等,就不能强行画进同一张图。我见过不少人在白板上把四个子空间画在一个坐标系里,还画得头头是道,那其实是错的——只有当 A 是方阵时,这种画法才勉强成立,一旦矩阵是长条的,直觉立刻崩坏。
实际操作建议:读完这一节,找一个 3×2 矩阵,比如 A = [[1, 2], [3, 6], [0, 0]],然后做下面四件事:
- 写出行空间:行向量是 (1, 2) 和 (3, 6),第二行是第一行的 3 倍,所以行空间是一条过原点的直线 y = 2x。
- 写出零空间:解 Ax=0,得到 x1 + 2x2 = 0,也是一条直线,且与行空间垂直。
- 写出列空间:列向量是 (1, 3, 0) 和 (2, 6, 0),第二个是第一个的 2 倍,所以列空间是三维空间里一条过原点的直线,方向 (1, 3, 0)。
- 写出左零空间:解 A^T y = 0,得到 y1 + 3y2 = 0,这是一个平面,法向量正是 (1, 3, 0)——也就是列空间的方向。
这个例子里秩 r = 1。行空间维数 1,零空间维数 n-r = 1;列空间维数 1,左零空间维数 m-r = 2。四个数字全部对得上,图也能画出来。这份 PDF 的价值,不是让你记住这四个空间的长相,而是让你记住「维数和正交补是一体的」。到了工程里,最小二乘、伪逆、自由度、线性约束,全都能从这四个空间里找到解释:一个线性系统有没有解、解有多少个自由度,本质上就是看 b 落在哪个子空间、零空间有多大。
2.3 特征值与奇异值的几何直觉:拉伸方向而不是解方程
特征值这一章,传统教材第一页就是 det(A - λI) = 0。等到你会解了,还是不知道 λ 在脑子里应该长什么样。这份 PDF 的切入点是几何:找一个非零向量 v,如果 Av 的结果只是把 v 拉长或缩短,但方向不变或反向,那 v 就是特征向量,标量 λ 就是特征值。所以特征分解不是「解一个多项式」,而是「在矩阵的变换里找到那些方向不变的直线」。
这个直觉有什么用?看一个 2×2 对称矩阵 [[2, 1], [1, 2]],特征值是 3 和 1,对应特征向量 (1, 1) 和 (-1, 1)。你只要画两个箭头就能看到:沿 (1, 1) 方向被拉长成 3 倍,沿 (-1, 1) 方向保持原长。非对称矩阵呢?取 [[1, 1], [0, 2]],特征值 1 和 2,特征向量分别是 (1, 0) 和 (1, 1),第二个特征方向是斜的,不再是坐标轴方向。这说明什么?对称矩阵的拉伸方向是正交的坐标轴,非对称矩阵则可能是斜的。
如果矩阵不可对角化,比如 [[1, 1], [0, 1]],特征值只有 1 但几何重数也是 1,方向不变的线只有一条,几何图像是「剪切」而不是「拉伸」。这种怪例在 PDF 里很少画,但恰恰是你必须警惕的边界:不是所有矩阵都能用一组正交方向描述清楚。
奇异值分解是特征值的推广。任何矩阵,包括不是方阵、没有足够特征向量的矩阵,都能分解成 A = U Σ V^T。几何上理解是:先把坐标旋转一下,再沿坐标轴拉伸,再旋转一次。PDF 用一张「把单位圆变成椭圆」的图,让读者直接看到奇异值就是椭圆半轴的拉伸倍数。这一节读完,你应该得到三个判断:特征值描述「有没有方向不变」,奇异值描述「每个正交方向的拉伸倍数」,两者的切点在对称矩阵上——对称矩阵的奇异值恰好等于特征值的绝对值。
3. 照着 PDF 做自己的插图:用 Numpy 复现线性组合与线性变换的核心代码
读图是一回事,自己画图是另一回事。这份 PDF 的插图美则美矣,但如果你只在别人画好的图里点头,很快就会忘。这一章我把三个最核心的图用 Python 做出来:矩阵乘法的列组合、正交子空间、特征值拉伸椭圆。每一段代码你都能直接跑,跑完把参数改一改,就成了你自己的直觉训练器。
3.1 最小复现:把矩阵乘法画成列的线性组合
二维矩阵最适合练手,因为箭头画得出来。下面的代码用 numpy 做数值验证,用 matplotlib 画箭头,把「Ax 是列的线性组合」这件事变成眼睛能看到的动作。
import numpy as np import matplotlib.pyplot as plt A = np.array([[2, 1], [1, 3]]) x = np.array([1, 2]) # 从列视角计算 A @ x:取两列按权重相加 col1 = A[:, 0] # 第一列 (2, 1) col2 = A[:, 1] # 第二列 (1, 3) combined = x[0] * col1 + x[1] * col2 result = A @ x # 直接用矩阵乘法验证 print("列组合结果:", combined) print("A @ x 结果:", result) fig, ax = plt.subplots(figsize=(5, 5)) origin = [0, 0] for vec, color, label in [ (col1, "C0", "col 1"), (col2, "C1", "col 2"), (combined, "C2", "1*col1 + 2*col2"), ]: ax.annotate("", xy=vec, xytext=origin, arrowprops=dict(color=color, width=2, headwidth=6)) ax.text(vec[0], vec[1], label, color=color) ax.set_xlim(-1, 8) ax.set_ylim(-1, 8) ax.set_aspect("equal") plt.show()逻辑说明:x[0] * col1 + x[1] * col2是逐元素乘法再相加,对应 PDF 里「先走第一步箭头,再走第二步箭头」;A @ x是 numpy 的矩阵乘法,两种算法结果必须完全一致。上面代码里A[:, 0]取第一列、A[:, 1]取第二列,numpy 的行列索引从 0 开始,写错列下标是最常见的报错来源。
参数说明:x = np.array([1, 2])是线性组合的权重,你把权重改成正负混合,比如[-1, 2],箭头方向立刻会变,这能直观看到「线性组合」不止是加法,还有反方向缩放。ax.set_aspect("equal")保证横纵轴比例一致,否则箭头方向会被画歪,几何直觉就毁了——这个小参数值得记住。
3.2 画出一对正交的子空间:秩一矩阵的零空间与行空间
PDF 里最容易被误解、但最值得自己画一遍的,是「零空间与行空间正交」这句话。用秩一矩阵画最直观。取 A = [[1, 2], [2, 4]],它只有一行独立的行向量,行空间就是 (1, 2) 这条线;零空间是解 Ax=0,得到 x = t·(2, -1),正好与 (1, 2) 垂直。
import numpy as np import matplotlib.pyplot as plt A = np.array([[1, 2], [2, 4]]) # 秩为 1 的矩阵 # 行空间方向:取第一个行向量并单位化 row_dir = A[0] / np.linalg.norm(A[0]) # 零空间方向:解 Ax=0 得到 (2, -1),单位化 null_dir = np.array([2.0, -1.0]) null_dir = null_dir / np.linalg.norm(null_dir) # 数值验证正交性 print("行空间与零空间点积:", np.dot(row_dir, null_dir)) fig, ax = plt.subplots(figsize=(5, 5)) for vec, color, label in [(row_dir, "C0", "row space"), (null_dir, "C1", "null space")]: ax.annotate("", xy=vec * 3, xytext=(0, 0), arrowprops=dict(color=color, width=2, headwidth=6)) ax.text(*(vec * 3), label, color=color) ax.set_xlim(-3, 3) ax.set_ylim(-3, 3) ax.set_aspect("equal") ax.axhline(0, color="gray", lw=0.5) ax.axvline(0, color="gray", lw=0.5) plt.show()逻辑说明:row_dir = A[0] / np.linalg.norm(A[0])把行向量变成单位向量,只取方向;零空间同理。之所以可以放心地让它们正交,是因为线性代数定理保证行空间和零空间是正交补,但这里的正交需要在同一个坐标系下观察——而这正是很多人画图时犯错的地方,下一章我会专门讲。
参数说明:vec * 3把方向向量拉长 3 倍,只是为了让箭头在图上更可见;np.linalg.norm用作归一化,如果你不关心箭头长度,可以省略归一化,直接画原始向量,但那样两个箭头的长度差异会干扰你对「方向」的判断。
3.3 把特征值画成椭圆:单位圆在矩阵下如何被拉伸
最后复现一份 PDF 里最著名的一张图:单位圆被对称矩阵变成椭圆。这里的矩阵选 [[2, 1], [1, 2]],特征值 3 和 1,椭圆的长轴沿 (1, 1) 方向、短轴沿 (-1, 1) 方向,长轴长度是短轴的 3 倍。
import numpy as np import matplotlib.pyplot as plt A = np.array([[2, 1], [1, 2]]) eigvals, eigvecs = np.linalg.eig(A) print("特征值:", eigvals) print("特征向量(按列):", eigvecs) theta = np.linspace(0, 2 * np.pi, 300) circle = np.column_stack([np.cos(theta), np.sin(theta)]) # 单位圆上的点,行向量形式 # 逐点右乘 A:注意用的是 A.T image = circle @ A.T fig, ax = plt.subplots(figsize=(6, 6)) ax.plot(circle[:, 0], circle[:, 1], "k--", label="unit circle") ax.plot(image[:, 0], image[:, 1], "C0", label="after A") ax.axhline(0, color="gray", lw=0.5) ax.axvline(0, color="gray", lw=0.5) ax.set_aspect("equal") ax.legend() plt.show()逻辑说明:np.linalg.eig返回的特征向量按列排列,第 i 列对应第 i 个特征值;circle是行向量组成的矩阵,circle @ A.T表示对每个行向量右乘 A。为什么不是A @ circle.T?因为后者得到的是 2×300 的矩阵,画图时还得再转置,而用行向量形式可以直接逐行画点。
参数说明:theta取 300 个点,是为了让椭圆边缘足够光滑;eigvals的返回顺序不保证排序,如果你发现长轴和短轴对不上,先np.sort(eigvals)再对照。改 A 矩阵为 [[1, 1], [0, 2]],你会看到椭圆轴不再与坐标轴平行,这正是非对称矩阵的特征。
4. 读 PDF 翻车的 4 个常见问题:为什么看懂了图还是不会做题
任何可视化资料都有同一个陷阱:视觉上「看懂了」,大脑以为自己掌握了,实际上只是多认了一张图。接下来这四类问题,是我在带人读这份 PDF 时遇到的真实高频翻车点,每一条都按「现象 → 原因 → 解决」的顺序说清楚,方便你直接对照自查。
4.1 看图全会,做题全废
现象:把 PDF 当画册翻完,每一张图都点头,合上书却连一个 3×3 方程组的通解都不会求,判断有解无解还要靠猜。
原因:PDF 的图是验证工具,不是计算工具。它把结论可视化,但没有替代行化简、消元这些体力活;你把「看得懂」误会成了「会推导」。图告诉你零空间与行空间正交,但没有告诉你怎么通过自由变量把零空间解出来。
解决:每读完一张图,给自己加一条铁律——先用笔把对应的 Ax=b 完整解一遍,再把解出来的向量放回图里看位置。画零空间之前,必须亲手把 A 化成行最简形,找到自由变量,再验证自由变量对应的方向确实与行空间正交。图只有在你自己推过之后,才是你的图。
4.2 四个子空间画成了一锅粥
现象:复习时想画四个子空间的关系,随手就在一个坐标系里同时画出行空间、零空间、列空间和左零空间,还画得头头是道。最后得出「行空间与列空间在一个平面里相交」这种错误结论。
原因:行空间活在 n 维空间,列空间活在 m 维空间,当 m ≠ n 时两者根本不在同一个坐标系里。PDF 故意把它们拆在不同画布上,就是为了防止这种混淆。很多人忽略了这个前提,把四张图强行叠在一起,直觉自然崩坏。
解决:画图前先写清楚 A 的形状,比如 3×2、秩 1。然后遵守一条规则:行空间与零空间画一个坐标系,列空间与左零空间画另一个坐标系。每次只画一对,用颜色区分,不要在同一张图里塞满四个子空间。重复几次之后,正交补的关系反而记得更牢。
4.3 特征值图只适用于「好矩阵」
现象:把书上的特征值椭圆图套用到 [[1, 1], [0, 1]] 这种矩阵上,发现单位圆没有变成正椭圆,方向不变的线只有一条,书上展示的「拉伸」图像失效了。
原因:PDF 绝大多数插图默认矩阵可对角化、特征值互异,这是为了视觉清晰。现实中很多矩阵有重特征值、复特征值,甚至没有一组完整的特征向量。你以为自己在看「特征值的一般图像」,其实只是在看「可对角化矩阵的典型图像」。
解决:动手画图前,先调np.linalg.eig看一眼特征值:有重根就要警惕,有复特征值就别用实平面画,特征向量凑不够 n 个时改画 SVD 的椭圆。记住一个口诀:可对角化画特征分解,不可对角化画剪切,非方阵直接画 SVD。
4.4 只看图不用数字验证
现象:顺着 PDF 的示例看完很爽,回头在自己手头的真实数据矩阵上套图,发现行列式、秩、条件数都不像书上的例子那样「干净」,图对不上。
原因:书里的矩阵都经过精心挑选,数值很整:行向量成倍数、特征值刚好是整数、秩一眼可见。真实数据的矩阵充满噪音,列之间几乎线性相关,奇异值差距巨大,直接套图当然水土不服。
解决:每一类图配一个最小验证脚本。遇到真实数据,先打印三样东西:shape、np.linalg.matrix_rank、np.linalg.cond,再决定用「秩一图」还是「完整 SVD 图」。如果秩亏缺,先做降维或正则化再画,否则画出来的图会被数值噪音淹没。
5. 把 PDF 的直觉搬进工程:投影、最小二乘与 SVD 降维的落地对照
读图的终点是能在工程问题里用上。这一章我们把这份 PDF 里的三张核心图,分别映射到三个最常见的工程场景:正规方程、共线性诊断、主成分分析。你会发现,几何直觉不是摆设,它能直接指导你选择用什么函数、避开什么坑。
5.1 最小二乘不用 inv:用投影图理解 X^T X 的条件
工程场景:拟合 y = β0 + β1·x,样本矩阵 X 是 n×2,第一列全 1,第二列是特征值。X 的两列张成一个平面,观测值 b 通常不在这个平面上。最小二乘的解 β 让残差 e = b - Xβ 与 X 的每一列都正交——这就是 PDF 里投影那张图的完整含义。
import numpy as np X = np.array([[1, 1], [1, 2], [1, 3], [1, 4]], dtype=float) b = np.array([2.1, 2.9, 4.2, 5.1]) # 观察 X^T X 的条件数,判断是否接近奇异 print("X^T X 条件数:", np.linalg.cond(X.T @ X)) # 正规方程解法:对条件数小的矩阵有效 beta = np.linalg.solve(X.T @ X, X.T @ b) # 伪逆解法:数值更稳,对奇异矩阵也能给最小范数解 beta_pinv = np.linalg.pinv(X) @ b y_hat = X @ beta print("残差与第一列正交:", np.dot(b - y_hat, X[:, 0])) print("残差与第二列正交:", np.dot(b - y_hat, X[:, 1]))逻辑说明:np.linalg.solve(X.T @ X, X.T @ b)是正规方程的教科书写法,前提是 X^T X 可逆;np.linalg.pinv(X) @ b基于 SVD,对接近奇异或严格奇异的矩阵也能返回最小二乘意义下的最小范数解。最后两行打印验证了 PDF 投影图的核心性质:残差与列空间正交。
参数说明:np.linalg.cond返回条件数。条件数接近 1 表示列空间方向健康;超过 1e6 就说明 X 的两列高度相关,此时正规方程数值不稳定,应该改用pinv或加正则。这个诊断放在solve之前,能帮你避免「解出来了但全是噪音」的翻车时刻。
5.2 从 SVD 图到 PCA:U、Σ、V^T 各自承担什么角色
工程场景:50 行 5 列的数据,希望降到 2 维。SVD 把中心化后的数据矩阵 Xc 拆成 U、Σ、V^T 三块:V^T 的行是主成分方向,U 的列是样本在新坐标系的坐标骨架,Σ 的对角是拉伸倍数,也就是各方向的重要性。PDF 里那张椭圆图,到这里变成了真实的降维操作。
import numpy as np rng = np.random.default_rng(42) X = rng.standard_normal((50, 5)) Xc = X - X.mean(axis=0) # 按列中心化,这一步不能省 U, s, Vt = np.linalg.svd(Xc, full_matrices=False) var_ratio = (s ** 2) / np.sum(s ** 2) # 各主成分解释的方差比例 pc1 = Vt[0] # 第一主成分方向 score = Xc @ pc1 # 样本在第一主成分上的投影 print("奇异值:", s) print("方差比例:", var_ratio) print("最大方差方向:", pc1)逻辑说明:中心化后,Xc^T·Xc 的协方差矩阵特征分解得到的特征向量,与 SVD 返回的 V 的行向量一致;s ** 2 / (n - 1)对应每个主成分的方差,所以var_ratio直接告诉你要保留几个维度。full_matrices=False返回紧凑 SVD,只保留非零奇异值对应的行列,避免算出无意义的零空间基底。
参数说明:np.random.default_rng(42)固定随机种子,保证结果可复现;axis=0表示按列计算均值。如果忘了中心化,第一主成分会被均值方向带偏,这跟 PDF 里「列空间原点在零向量」的设定是一回事——不做中心化,原点都不对,投影自然全歪。
6. 把它当索引而不是教材:按图索骥的阅读习惯与验证技巧
这份 PDF 不是按章节顺序读的,它更像一张线性代数地图。我自己的习惯是把它当索引:遇到一个矩阵问题,先在脑子里搜索它对应 PDF 里的哪张图。问「Ax=b 有没有解」,就翻列空间与零空间那几页;问「怎么拟合一条线」,就翻投影那张图;问「怎么压缩数据」,直接跳到 SVD 的椭圆图。带着问题看图,比从头到尾刷一遍有效得多。
第二个习惯是「每个结论必须数字验证」。图里说行空间与零空间正交,我就随手取一个 2×2 矩阵,用np.dot验算;图里说对称矩阵特征值等于奇异值,我就取一个 3×3 对称矩阵,分别调np.linalg.eig和np.linalg.svd对比。绝大多数人对这个 PDF 的怀疑,都在这一步消失。
第三个技巧,是把维度写在图旁边。每看一张图,先标 m、n、r 三个数,再看图。比如 3×2 矩阵,秩 1,那么行空间和零空间各是几维,列空间和左零空间各是几维——先写数字,再看图,不容易被画上的线条带偏。这个习惯后来成了我解决所有线性代数问题的第一步:不画图不写维度,坚决不开算。
很多从背公式过来的人,包括我自己,看到这份中文版的时候都有同一个感觉:那些当年靠死记硬背才熬过去的定理,如果早点见到图,可能根本不用背。但图不会替你做题,它只负责把方向指对,剩下的消元、求逆、分解,还是得靠手和代码。希望这篇笔记能让你把它用成地图,而不是另一本积灰的 PDF,希望帮到你。
本文还有配套的精品资源,点击获取