线性代数的几何意义 - 任广千/谢聪/胡翠芳

本书使用向量的概念对国内高校工科"线性代数"的课程内容进行了较全面的几何分析,把上百个概念和定理的几何意义串在一起。
关于作者
任广千、谢聪、胡翠芳 是线性代数教育领域的实践者:
- 高校教师:长期从事线性代数教学与研究
- 教育创新者:致力于将抽象的代数概念几何化、直观化
- 技术作家:希望通过通俗的方式让更多人理解线性代数的本质
核心内容
1. 向量的几何意义
import numpy as np
import matplotlib.pyplot as plt
# 向量:既有大小又有方向的量
# 几何表示:从原点出发的有向线段
# 二维向量
v1 = np.array([3, 2])
v2 = np.array([-1, 4])
# 向量加法:平行四边形法则
v_add = v1 + v2 # [2, 6]
# 向量减法:三角形法则
v_sub = v1 - v2 # [4, -2]
# 数乘:缩放或反向
v_scaled = 2 * v1 # [6, 4]
v_negated = -v1 # [-3, -2]
# 向量的模(长度)
norm = np.linalg.norm(v1) # √(3² + 2²) = √13
# 单位向量(方向不变,长度为 1)
v_unit = v1 / np.linalg.norm(v1)
# 点积(内积):衡量两个向量的"相 似程度"
# a · b = |a||b|cos(θ) = a₁b₁ + a₂b₂
dot_product = np.dot(v1, v2)
# 夹角
cos_theta = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
theta = np.arccos(np.clip(cos_theta, -1, 1))
# 应用:
# - 投影:一个向量在另一个向量上的投影
# - 正交:点积为 0 表示垂直
# - 相似度:余弦相似度 = cos(θ)
2. 矩阵的几何意义
# 矩阵:线性变换的表示
# 矩阵 × 向量 = 对向量进行变换
A = np.array([[2, 0],
[0, 1]])
v = np.array([1, 1])
# 矩阵变换
v_transformed = A @ v # [2, 1]
# 这个矩阵 表示 x 方向拉伸 2 倍
# 常见变换矩阵
# 1. 缩放变换
scale_x = np.array([[2, 0],
[0, 1]]) # x 方向拉伸 2 倍
scale_y = np.array([[1, 0],
[0, 0.5]]) # y 方向压缩 2 倍
# 2. 旋转变换(逆时针θ角)
theta = np.pi / 4 # 45 度
rotation = np.array([
[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]
])
# 3. 剪切变换
shear_x = np.array([[1, 1],
[0, 1]]) # x 方向剪切
shear_y = np.array([[1, 0],
[1, 1]]) # y 方向剪切
# 4. 反射变换
reflect_x = np.array([[1, 0],
[0, -1]]) # 关于 x 轴反射
reflect_y = np.array([[-1, 0],
[0, 1]]) # 关于 y 轴反射
# 矩阵乘法:复合变换
# C = AB 表示先进行 B 变换,再进行 A 变换
combined = rotation @ scale_x # 先缩放,再旋转
3. 行列式的几何意义
# 行列式:线性变换的"缩放因子"
# |det(A)| > 1: 面积/体积放大
# |det(A)| < 1: 面积/体积缩小
# det(A) = 0: 降维(不可逆)
# det(A) < 0: 方向翻转
A = np.array([[2, 0],
[0, 3]])
det_A = np.linalg.det(A) # 6
# 表示面积放大了 6 倍
B = np.array([[1, 2],
[3, 4]])
det_B = np.linalg.det(B) # -2
# 负号表示方向翻转(如镜像)
# 几何应用
# 1. 平行四边形面积 = |det([a, b])|
# 其中 a, b 是相邻两边的向量
# 2. 平行六面体体积 = |det([a, b, c])|
# 3. 判断矩阵是否可逆
if np.isclose(det_A, 0):
print("矩阵不可逆(降维)")
else:
print("矩阵可逆")
# 4. 判断线性方程组解的情况
# det(A) ≠ 0: 唯一解
# det(A) = 0: 无解或无穷多解
4. 特征值与特征向量
# 定义:Av = λv
# 特征向量 v: 经过变换 A 后,方向不变的向量
# 特征值λ: 特征向量 的缩放倍数
A = np.array([[3, 1],
[0, 2]])
eigenvalues, eigenvectors = np.linalg.eig(A)
# λ₁ = 3, v₁ = [1, 0]
# λ₂ = 2, v₂ = [-0.707, 0.707]
# 几何意义
# 1. 特征向量是变换的"主轴"方向
# 2. 特征值是该方向上 的缩放因子
# 应用:主成分分析 (PCA)
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)
# 协方差矩阵的特征值 = 各主成分的方差
# 特征向量 = 主成分方向
# 应用:矩阵对角化
# A = PDP^(-1)
# 其中 D 是对角矩阵(对角线是特征值)
# P 的列是特征向量
# 应用:马尔可夫链稳态
# 稳态分布是转移矩阵特征值为 1 的特征向量
# 应用:Google PageRank
# 网页重要性是链接矩阵的主特征向量
5. 线性方程组的几何意义
# 方程组 Ax = b 的几何解释
# 行观点:每个方程表示一个平面(或直线)
# 解是这些平面的交点
# 列观点:b 是 A 的列向量的线性组合
# 解是组合系数
A = np.array([[2, 1],
[1, -1]])
b = np.array([5, 1])
# 解法 1:直接求解
x = np.linalg.solve(A, b) # [2, 1]
# 解法 2:逆矩阵
A_inv = np.linalg.inv(A)
x = A_inv @ b
# 解的存在性
# rank(A) = rank([A|b]) = n: 唯一解
# rank(A) = rank([A|b]) < n: 无穷多解
# rank(A) ≠ rank([A|b]): 无解
# 齐次方程组 Ax = 0
# 总有零解
# det(A) ≠ 0: 只有零解
# det(A) = 0: 有非零解(无穷多解)
# 最小二乘解(当无解时)
# 找到使 ||Ax - b||² 最小的 x
x_ls = np.linalg.lstsq(A, b, rcond=None)[0]
6. 向量空间与基
# 向量空间:对加法和数乘封闭的集合
# 基 (Basis): 线性无关的生成集
# 维数:基中向量的个数
# R² 的标准基
e1 = np.array([1, 0])
e2 = np.array([0, 1])
# 任意向量都可表示为基的线性组合
v = np.array([3, 4])
v = 3 * e1 + 4 * e2
# 非标准基
b1 = np.array([1, 1])
b2 = np.array([1, -1])
# v 在新基下的坐标
B = np.column_stack([b1, b2])
v_new_coords = np.linalg.solve(B, v) # [3.5, -0.5]
# 验证
v_reconstructed = v_new_coords[0] * b1 + v_new_coords[1] * b2
# 基变换矩阵(过渡矩阵)
# 从旧基到新基的变换
# 应用:坐标变换
# 在计算机图形学中,经常需要在不同坐标系间转换
# 世界坐标 → 相机坐标 → 屏幕坐标
# 应用:特征脸 (Eigenfaces)
# 人脸图像可以表示为"特征脸"基的线性组合
7. 正交性与投影
# 正交:向量垂直(点积为 0)
# 标准正交:正交且为单位向量
v1 = np.array([1, 0, 0])
v2 = np.array([0, 1, 0])
v3 = np.array([0, 0, 1])
# 标准正交基
# v1·v2 = 0, v1·v3 = 0, v2·v3 = 0
# ||v1|| = ||v2|| = ||v3|| = 1
# 投影:一个向量在另一个向量上的"影子"
# proj_b(a) = (a·b / b·b) * b
def project(a, b):
return np.dot(a, b) / np.dot(b, b) * b
# 正交投影矩阵
# P = A(A^T A)^(-1) A^T
def projection_matrix(A):
return A @ np.linalg.inv(A.T @ A) @ A.T
# 最小二乘的几何解释
# 当 Ax = b 无解时,找到 b 在 A 列空间上的投影
# Gram-Schmidt 正交化
# 将任意基转换为标准正交基
def gram_schmidt(vectors):
ortho_basis = []
for v in vectors:
u = v.copy()
for e in ortho_basis:
u -= project(v, e)
if np.linalg.norm(u) > 1e-10:
ortho_basis.append(u / np.linalg.norm(u))
return np.array(ortho_basis)
# QR 分解:A = QR
# Q 是正交矩阵,R 是上三角矩阵
Q, R = np.linalg.qr(A)
8. 奇异值分解 (SVD)
# SVD: A = UΣV^T
# 任意矩阵都可以分解为三个矩阵的乘积
# U: m×m 正交矩阵(左奇异向量)
# Σ: m×n 对角矩阵(奇异值)
# V: n×n 正交矩阵(右奇异向量)
A = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]])
U, sigma, VT = np.linalg.svd(A, full_matrices=False)
# 几何意义
# 1. 任何线性变换都可以分解为:
# 旋转 (V^T) → 缩放 (Σ) → 旋转 (U)
# 2. 奇异值表示各方向的重要性
# 应用:数据压缩
# 只保留前 k 个大的奇异值
k = 2
A_approx = U[:, :k] @ np.diag(sigma[:k]) @ VT[:k, :]
# 应用:推荐系统
# 用户 - 物品矩阵的 SVD
# 发现隐含的用户偏好和物品特征
# 应用:图像压缩
# 将图像视为矩阵,进行 SVD 分解
# 保留主要奇异值,实现压缩
# 应用:去噪
# 小奇异值通常对应噪声
# 截断 SVD 可以去除噪声
经典摘录
线性代数的本质是空间变换。向量是空间中的箭头,矩阵是改变箭头的机器。
行列式告诉你空间被拉伸或压缩了多少,特征向量告诉你哪些方向在变换中保持不变。
矩阵乘法不是数字的乘法,而是变换的复合。
SVD 揭示了任意矩阵的内在结构,是线性代 数中最有用的分解。
理解线性代数的几何意义,让抽象的公式变得直观可见。
读书心得
《线性代数的几何意义》是一本独特的线性代数入门书籍。与传统教材不同,这本书从几何视角出发,让抽象的代数概念变得直观可感。
书中对我影响最深的是矩阵作为线性变换的观点。一旦理解了矩阵乘法就是对向量进行变换,很多原本抽象的概念就变得清晰了:
- 行列式是变换的缩放因子
- 特征向量是变换中方向不变的向量
- SVD 是旋转 - 缩放 - 旋转的分解
特征值与特征向量的几何解释也非常精彩。它们不是凭空定义的概念,而是描述了变换的"主轴"和"缩放倍数"。理解了这一点,PCA、PageRank 等应用就变得容易理解了。
SVD 分解的部分让我印象深刻。这个看似复杂的分解,几何上只是三个简单变换的复合:旋转→缩放→旋转。理解了这一点,SVD 在数据压缩、推荐系统、图像处理等领域的应用就水到渠成了。
对于机器学习从业者来说,线性代数是必备基础:
- 神经网络 = 矩阵乘法 + 非线性激活
- PCA = 特征值分解
- 最小二乘 = 向量投影
- 推荐系统 = 矩阵分解
这本书能帮助读者建立对线性代数的直观理解,是学习机器学习和深度学习的良好前置知识。
建议配合 3Blue1Brown 的"线性代数的本质"系列视频一起学习,几何直观 + 代数推导 ,效果更佳。