奇异值分解(SVD)是一个强大的矩阵分解工具,广泛应用于数据降维、图像压缩、机器学习等领域。然而,对于大规模数据或高维矩阵,计算和存储的开销非常大,因此提出了多种简化版的 SVD 方法。这些简化版方法在保证解的精度的同时,能够显著减少计算量和内存占用。
本文将详细介绍几种简化版 SVD 方法,包括经济型 SVD、随机化 SVD、增量 SVD、分块 SVD 和偏最小二乘法(PLS),并通过数学公式详细解释这些方法。
给定一个矩阵 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n,奇异值分解(SVD)将其分解为三个矩阵的乘积:
A = U Σ V T A = U \Sigma V^T A=UΣVT
SVD 常用于求解最小二乘问题,其中的目标是最小化目标函数:
min θ ∥ A θ − b ∥ 2 2 \min_{\theta} \|A\theta - b\|_2^2 θmin∥Aθ−b∥22
其中 A A A 是矩阵, b b b 是目标值, θ \theta θ 是需要求解的未知向量。通过 SVD 分解 A A A,我们可以得到解:
θ = V Σ − 1 U T b \theta = V \Sigma^{-1} U^T b θ=VΣ−1UTb
经济型 SVD 是对标准 SVD 的一种优化。假设矩阵 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n 进行 SVD 分解时,得到的矩阵 U ∈ R m × m U \in \mathbb{R}^{m \times m} U∈Rm×m 和 V T ∈ R n × n V^T \in \mathbb{R}^{n \times n} VT∈Rn×n 的维度通常很大,而实际需要的只是 r r r 个奇异值和对应的奇异向量,其中 r r r 是矩阵 A A A 的秩。
经济型 SVD 只计算和存储矩阵的前 r r r 个奇异值和对应的奇异向量,减少了计算和存储开销:
A = U r Σ r V r T A = U_r \Sigma_r V_r^T A=UrΣrVrT
这种方法适用于低秩矩阵和降维任务。
随机化 SVD 是通过引入随机矩阵来近似计算 SVD。其基本思路是使用一个随机矩阵 Ω ∈ R n × k \Omega \in \mathbb{R}^{n \times k} Ω∈Rn×k,将矩阵 A ∈ R m × n A \in \mathbb{R}^{m \times n} A∈Rm×n 投影到低维空间:
Y = A Ω Y = A \Omega Y=AΩ
然后对低维矩阵 Y Y Y 执行标准 SVD 分解:
Y = U k Σ k V k T Y = U_k \Sigma_k V_k^T Y=UkΣkVkT
通过低维矩阵 Y Y Y 的 SVD,我们可以获得矩阵 A A A 的近似解。该方法的核心是用随机矩阵进行数据投影,使得高维数据的 SVD 计算变得更快速。
A ≈ U k Σ k V k T A \approx U_k \Sigma_k V_k^T A≈UkΣkVkT
其中 U k ∈ R m × k U_k \in \mathbb{R}^{m \times k} Uk∈Rm×k, Σ k ∈ R k × k \Sigma_k \in \mathbb{R}^{k \times k} Σk∈Rk×k, V k T ∈ R k × n V_k^T \in \mathbb{R}^{k \times n} VkT∈Rk×n。
增量 SVD 适用于处理动态数据流,它可以在新数据到来时逐步更新已有的 SVD,而不需要每次都从头开始计算。该方法通过增量更新奇异值和奇异向量来避免全量重算。
假设我们已经有了矩阵 A 0 A_0 A0 的 SVD 分解:
A 0 = U 0 Σ 0 V 0 T A_0 = U_0 \Sigma_0 V_0^T A0=U0Σ0V0T
当新的数据 A new A_{\text{new}} Anew 加入时,增量 SVD 通过更新现有的分解得到新的 SVD。
A updated = [ A 0 A new ] A_{\text{updated}} = [A_0 \; A_{\text{new}}] Aupdated=[A0Anew]
我们使用现有的 SVD 解 U 0 , Σ 0 , V 0 T U_0, \Sigma_0, V_0^T U0,Σ0,V0T 来合并新数据,得到更新后的解。
分块 SVD 是将矩阵分割成多个小块进行分解的技术。这种方法将大矩阵分解成更小的矩阵块,并对每个块进行独立的 SVD 计算。最后,合并各个块的结果。
假设矩阵 A A A 被分成 k k k 个小块:
A = [ A 1 A 2 … A k ] A = \begin{bmatrix} A_1 & A_2 & \dots & A_k \end{bmatrix} A=[A1A2…Ak]
然后对每个小块 A i A_i Ai 执行 SVD 分解:
A i = U i Σ i V i T A_i = U_i \Sigma_i V_i^T Ai=UiΣiViT
将每个小块的 SVD 结果合并,得到整体矩阵的分解:
A = [ U 1 U 2 … U k ] [ Σ 1 Σ 2 … Σ k ] [ V 1 T V 2 T … V k T ] A = \begin{bmatrix} U_1 & U_2 & \dots & U_k \end{bmatrix} \begin{bmatrix} \Sigma_1 & \Sigma_2 & \dots & \Sigma_k \end{bmatrix} \begin{bmatrix} V_1^T & V_2^T & \dots & V_k^T \end{bmatrix} A=[U1U2…Uk][Σ1Σ2…Σk][V1TV2T…VkT]
偏最小二乘法(PLS)是通过同时降维输入矩阵和输出矩阵来解决回归问题。PLS 实际上与 SVD 紧密相关,它通过分解输入数据 X X X 和输出数据 Y Y Y 来找到同时解释输入和输出之间关系的潜在成分。
在 PLS 中,输入矩阵 X X X 和输出矩阵 Y Y Y 的分解如下:
X = T P T , Y = U Q T X = T P^T, \quad Y = U Q^T X=TPT,Y=UQT
其中, T T T 和 U U U 是潜在的成分, P P P 和 Q Q Q 是与输入和输出变量的关系矩阵。
min θ ∥ X θ − Y ∥ 2 2 \min_{\theta} \|X\theta - Y\|_2^2 θmin∥Xθ−Y∥22
通过 PLS,我们可以降低数据的维度,同时保持预测性能。
下面是一个使用经济型 SVD 的代码示例:
% 生成示例矩阵
A = randn(100, 50); % 一个 100 x 50 的矩阵
% 使用经济型 SVD 进行分解
[U, S, V] = svd(A, 'econ');
% 输出前 5 个奇异值
disp('前 5 个奇异值:');
disp(diag(S(1:5, 1:5)));
% 输出 U 和 V 的维度
disp('U 的维度:');
disp(size(U));
disp('V 的维度:');
disp(size(V));