← 返回Book 2目录
第28章

奇异值分解(SVD)

Singular Value Decomposition

A = U·Σ·V^T 任意矩阵分解为三个简单变换

28.1 什么是奇异值分解?

奇异值分解(SVD)将任意矩阵A分解为:A = U·Σ·V^T

🔄 V^T 旋转

正交矩阵V,在输入空间旋转坐标系,找到主方向

📏 Σ 缩放

对角矩阵Σ,沿主轴缩放,奇异值决定拉伸程度

🔄 U 旋转

正交矩阵U,在输出空间旋转,完成最终变换

💡 SVD适用于任意形状的矩阵:方阵、细高(升维)、矮胖(降维)

28.2 可视化2×2方阵SVD

A = U·Σ·V^T 分解为三步:旋转 → 缩放 → 旋转

数据矩阵:平面散点集X的列排成矩阵形式

原始11×11正交网格,颜色映射RdYlBu

矩阵 A

A = [[5/4, -3/4],
     [-3/4, 5/4]]

对称矩阵,特征值=奇异值

SVD分解

U = [[-√2/2,  √2/2],
     [-√2/2, -√2/2]]
     
Σ = [[2,   0],
     [0, 0.5]]
     
V = U (对称矩阵)
Python核心代码:
# 生成网格
x = np.linspace(-5, 5, 11)
X1, X2 = np.meshgrid(x, x)
X = np.column_stack([X1.ravel(), X2.ravel()])

# SVD分解
U, s, Vt = np.linalg.svd(A)

# 分步变换
Y_v = X @ V
Y_vs = Y_v @ np.diag(s)
Y_complete = Y_vs @ U.T  # = X @ A.T

28.3 可视化3×3方阵SVD

三维空间线性变换分解:旋转 → 缩放 → 旋转

RGB立方体三个彩色外框线

矩阵 A

A = [[0,  1,  1],
     [1,  0,  1],
     [-1, -1, 0]]

det(A) = -2,包含镜像变换

奇异值

σ₁ = 2
σ₂ = 1  
σ₃ = 1

σ₁最大,该方向拉伸最显著

🎯 三维SVD分解的几何意义

V^T旋转:在输入3D空间找到主方向坐标系
Σ缩放:沿三个正交主轴分别拉伸/压缩
U旋转:在输出3D空间完成最终姿态调整
Python核心代码:
# RGB立方体三个外框线
X_red = np.column_stack([np.ones(n), np.linspace(0,1,n), np.zeros(n)])
X_green = np.column_stack([np.linspace(0,1,n), np.ones(n), np.zeros(n)])
X_blue = np.column_stack([np.ones(n), np.zeros(n), np.linspace(0,1,n)])
X = np.vstack([X_red, X_green, X_blue])

# SVD分解
U, s, Vt = np.linalg.svd(A)

# 四个不同视角
fig, axes = plt.subplots(2, 2, subplot_kw={'projection': '3d'})
for ax, (elev, azim) in zip(axes.flat, views):
    ax.scatter(Y[:,0], Y[:,1], Y[:,2], c=colors)
    ax.view_init(elev=elev, azim=azim)

28.4 可视化3×2细高矩阵SVD(升维)

2D → 3D:平面旋转 → 缩放+补零 → 三维旋转

原始2D网格(11×11散点)

细高矩阵 A (3×2)

A = [[0, 1],
     [1, 1],
     [1, 0]]

输入2D → 输出3D,升维映射

SVD矩阵维度

U: 3×3 (输出空间旋转)
Σ: 3×2 (缩放+升维)
V: 2×2 (输入空间旋转)

奇异值: σ₁=√3, σ₂=1

🔺 升维的几何意义

• V^T:在输入2D平面旋转坐标系

• Σ^T:缩放+补零(第三坐标=0),数据嵌入3D的xy平面

• U:在3D空间旋转,将平面"倾斜"到新位置

⚠️ Σ矩阵是3×2,第三列全0 → 输出Z坐标受限

Python核心代码:
# 2D网格
x = np.linspace(-5, 5, 11)
X1, X2 = np.meshgrid(x, x)
X = np.column_stack([X1.ravel(), X2.ravel()])  # n×2

# SVD分解
U, s, Vt = np.linalg.svd(A)  # A是3×2
# U: 3×3, s: [√3, 1], Vt: 2×2

# 分步变换
Y_v = X @ V      # n×2
Y_vs = Y_v @ np.diag(s)  # 需要扩展Σ为3×2
Y = Y_vs @ U.T   # n×3,升维完成!

28.5 可视化2×3矮胖矩阵SVD(降维)

3D → 2D:三维旋转 → 缩放+投影 → 平面旋转

原始RGB立方体三条外框线

矮胖矩阵 A (2×3)

A = [[0, 1, 1],
     [1, 1, 0]]

输入3D → 输出2D,降维映射

SVD矩阵维度

U: 2×2 (输出空间旋转)
Σ: 2×3 (缩放+降维)
V: 3×3 (输入空间旋转)

奇异值: σ₁=√3, σ₂=1

📉 降维的几何意义

• V^T:在输入3D空间旋转,找到主方向

• Σ^T:缩放+投影(第三列=0),丢弃一个维度的信息

• U:在2D平面旋转,完成最终布局

⚠️ Σ矩阵是2×3,第三列全0 → Z方向信息被丢弃(PCA原理)

Python核心代码:
# RGB立方体三条外框线
X_red = np.column_stack([np.ones(n), np.linspace(0,1,n), np.zeros(n)])
X_green = np.column_stack([np.linspace(0,1,n), np.ones(n), np.zeros(n)])
X_blue = np.column_stack([np.ones(n), np.zeros(n), np.linspace(0,1,n)])
X = np.vstack([X_red, X_green, X_blue])  # n×3

# SVD分解
U, s, Vt = np.linalg.svd(A)  # A是2×3
# U: 2×2, s: [√3, 1], Vt: 3×3

# 分步变换
Y_v = X @ V      # n×3
Y_vs = Y_v @ np.diag(s)  # 需要Σ为2×3,第三列为0
Y = Y_vs @ U.T   # n×2,降维完成!

# 这就是PCA的数学基础

🎯 核心洞察与应用

几何直觉

  • 方阵:旋转→缩放→旋转,同维变换
  • 细高矩阵:平面旋转→升维+缩放→空间旋转
  • 矮胖矩阵:空间旋转→降维+缩放→平面旋转
  • 奇异值σᵢ越大,该方向越重要;σᵢ=0表示零空间

实际应用

  • PCA降维:保留最大奇异值对应的主方向
  • 推荐系统:矩阵分解挖掘潜在因子
  • 图像压缩:低秩近似减少存储空间
  • 自然语言处理:LSA潜在语义分析
  • 数值计算:求解线性方程组、最小二乘

统一框架:无论输入输出维度如何,SVD总能将线性变换分解为"旋转-缩放-旋转"三步。 这种统一性使SVD成为线性代数最强大的工具之一。