本站内容由 AI 生成,可能存在错误。如发现问题,欢迎到 GitHub Issues 反馈。

随机化 SVD:当精确分解算不动的时候

随机化 SVD:当精确分解算不动的时候

更新于 2026-04-23

上一篇我们看到 PCA 的核心计算就是 SVD——对中心化数据矩阵 X~=UΣVT\tilde{X} = U\Sigma V^T 求前 kk 个奇异向量。对于一个小规模矩阵,经典 SVD 算法(如 Golub-Kahan 双对角化)完全够用。但当矩阵规模变大时,问题来了。

精确 SVD 的代价:对一个 m×nm \times n 矩阵,经典 SVD 的复杂度是 O(mnmin(m,n))O(mn\min(m,n))。考虑一个现实场景——Netflix 的用户-电影评分矩阵大约是 480,000×17,000480{,}000 \times 17{,}000,全 SVD 的计算量约为 480,000×17,000×17,0001.4×1014480{,}000 \times 17{,}000 \times 17{,}000 \approx 1.4 \times 10^{14} 次浮点操作。即使在现代硬件上,这也需要数小时乃至数天。而在实际应用中,我们通常只需要前 kk(比如 50 或 100)个奇异值和奇异向量——全 SVD 做了太多不必要的工作。

核心思想:既然我们只要前 kk 个分量,何不先用一个随机投影将矩阵压缩到一个远小于原始维度的子空间,然后在这个小子空间里做精确 SVD?只要随机投影足够好——即它大致保持了矩阵的”重要方向”——最终结果就接近精确的截断 SVD。

这就是随机化 SVD(Randomized SVD)的思想。它的理论基础是一个看似违反直觉但异常深刻的结论:随机投影几乎保持距离——Johnson-Lindenstrauss 引理。

Johnson-Lindenstrauss 引理

直觉

JL 引理:随机投影几乎保持所有距离原始空间 ℝᵈ(d 可能很大)d₁₂f(x) = Ωx/√kΩ: 随机高斯矩阵投影空间 ℝᵏ(k ≥ 8 ln N / ε²)d'₁₂(1−ε)‖xᵢ−xⱼ‖² ≤ ‖f(xᵢ)−f(xⱼ)‖² ≤ (1+ε)‖xᵢ−xⱼ‖²

想象你有 NN 个点散布在 Rd\mathbb{R}^d 中,dd 很大(比如 10,000 维)。你想把这些点投影到低维空间(比如 k=50k = 50 维)以便存储和计算。一般来说,降维必然丢失信息,点与点之间的距离会被扭曲。

但 Johnson-Lindenstrauss(JL)引理告诉我们一个惊人的事实:只要目标维度 kklnN\ln N 成正比,一个随机线性投影就能同时保持所有点对之间的距离,失真不超过 ε\varepsilon

注意这里的关键词:

  • 随机:不需要精心设计投影矩阵,随机高斯矩阵就够了
  • 同时:不是保持某一对点的距离,而是所有 (N2)\binom{N}{2} 对的距离
  • dd 无关:目标维度只取决于点数 NN 和容差 ε\varepsilon,与原始维度 dd 完全无关

严格陈述

引理(Johnson & Lindenstrauss, 1984):给定 0<ε<10 < \varepsilon < 1NN 个点 x1,,xNRd\mathbf{x}_1, \ldots, \mathbf{x}_N \in \mathbb{R}^d,若

k8lnNε2k \geq \frac{8\ln N}{\varepsilon^2}

则随机线性映射 f(x)=1kΩxf(\mathbf{x}) = \frac{1}{\sqrt{k}}\Omega\mathbf{x}(其中 ΩRk×d\Omega \in \mathbb{R}^{k \times d},每个元素独立采样自 N(0,1)\mathcal{N}(0, 1))以高概率满足:对所有 1i,jN1 \leq i, j \leq N(即全部 (N2)\binom{N}{2} 个点对),

(1ε)xixj2f(xi)f(xj)2(1+ε)xixj2(1 - \varepsilon)\|\mathbf{x}_i - \mathbf{x}_j\|^2 \leq \|f(\mathbf{x}_i) - f(\mathbf{x}_j)\|^2 \leq (1 + \varepsilon)\|\mathbf{x}_i - \mathbf{x}_j\|^2

注意:经典陈述用”存在线性映射”,但证明是构造性的——你不需要搜索这个映射,随机生成 Ω\Omega 就行,它大概率满足条件。

“随机投影”是什么? 就是矩阵乘法 y=1kΩx\mathbf{y} = \frac{1}{\sqrt{k}}\Omega\mathbf{x}。原始向量 xRd\mathbf{x} \in \mathbb{R}^d,结果 yRk\mathbf{y} \in \mathbb{R}^kkdk \ll d)。Ω\Omega 的每一行是 Rd\mathbb{R}^d 中的一个随机方向,yi=1kωiTxy_i = \frac{1}{\sqrt{k}}\boldsymbol{\omega}_i^T\mathbf{x} 就是 x\mathbf{x} 在这个随机方向上的投影分量。kk 个随机方向一起,把高维信息”压缩”到 kk 维。1/k1/\sqrt{k} 是归一化因子,使得 y2\|\mathbf{y}\|^2 在期望意义下等于 x2\|\mathbf{x}\|^2

逐项理解各参数:

  • ε\varepsilon(epsilon):允许的最大相对失真。ε=0.1\varepsilon = 0.1 意味着距离最多变化 10%
  • NN:总点数。kk 的下界与 lnN\ln N 成正比,因为需要对全部 (N2)<N2/2\binom{N}{2} < N^2/2 个点对做 union bound——点越多,需要更高的维度来保证所有对同时不失真。但增长只是对数的:点数翻 1010 倍,kk 只需多 8ln10/ε218/ε28\ln 10 / \varepsilon^2 \approx 18/\varepsilon^2
  • k8lnN/ε2k \geq 8\ln N / \varepsilon^2:目标维度的下界,与原始维度 dd 完全无关。N=1,000,000N = 1{,}000{,}000 个点、ε=0.1\varepsilon = 0.1 时,k8×ln(106)/0.0111,053k \geq 8 \times \ln(10^6) / 0.01 \approx 11{,}053——从任意高维降到约一万维,所有距离保持 90%-110%

1/k1/\sqrt{k} 是必须的吗? 不是。不除的话,Ωx2\|\Omega\mathbf{x}\|^2 的期望是 kx2k\|\mathbf{x}\|^2——所有距离被统一放大 kk 倍,但 JL 保证的相对失真不受全局缩放影响(集中不等式控制的是 Ωx2/(kx2)\|\Omega\mathbf{x}\|^2/(k\|\mathbf{x}\|^2) 偏离 1 的程度)。如果只关心距离的排序(如最近邻搜索),1/k1/\sqrt{k} 完全不需要;如果需要投影后的距离在绝对数值上近似原始距离,就加上它。加 1/k1/\sqrt{k} 使 E[f(x)2]=x2\mathbb{E}[\|f(\mathbf{x})\|^2] = \|\mathbf{x}\|^2,公式更干净。

证明思路

完整证明超出本文范围,但核心思路值得一看。关键在于一个集中不等式(concentration inequality):

对单个向量 x\mathbf{x},随机投影 f(x)=1kΩxf(\mathbf{x}) = \frac{1}{\sqrt{k}}\Omega\mathbf{x} 的范数平方 f(x)2\|f(\mathbf{x})\|^2kk 个独立卡方变量之和(经缩放)。由 Hoeffding 不等式(或更精确的 sub-Gaussian 尾界):

Pr[f(x)2x2>εx2]2exp ⁣(kε28)\Pr\Big[\big|\|f(\mathbf{x})\|^2 - \|\mathbf{x}\|^2\big| > \varepsilon\|\mathbf{x}\|^2\Big] \leq 2\exp\!\Big(-\frac{k\varepsilon^2}{8}\Big)

x\mathbf{x} 替换为 xixj\mathbf{x}_i - \mathbf{x}_j,就得到单个点对的距离保持概率。对全部 (N2)<N2/2\binom{N}{2} < N^2/2 个点对取 union bound:

Pr[存在某对距离失真超过 ε]<N2exp ⁣(kε28)\Pr[\text{存在某对距离失真超过 } \varepsilon] < N^2 \exp\!\Big(-\frac{k\varepsilon^2}{8}\Big)

令右边 <1< 1,即 k>8lnN/ε2k > 8\ln N / \varepsilon^2——这就是 JL 引理的维度要求。

深层含义:JL 引理的力量在于它的通用性。不需要对数据做任何假设(无需低秩、无需稀疏、无需特殊分布),只要目标维度足够大,随机投影就能保持距离。这为随机化算法提供了坚实的理论基础。

可视化

用下面的交互组件亲手体验 JL 引理。我们生成 d=50d = 50 维的随机高斯点,投影到 kk 维,然后在散点图中对比每对点的原始距离和投影距离。如果 JL 引理成立,所有点应该落在对角线附近的 (1±ε)(1 \pm \varepsilon) 容差带内。

试试:先用很小的 kk(如 2-3),观察点偏离对角线的程度;然后逐渐增大 kk,观察点如何收敛到对角线。

Johnson-Lindenstrauss 引理:随机投影保持距离
高维点对 → 随机投影到低维 → 对比成对距离
0.03.56.910.413.917.40.03.56.910.413.917.4原始距离(高维)投影距离(低维)理想保持线 y = x(1±ε) 容差带 (ε=0.3)超出容差带
8
30
距离保持统计
原始维度 d:50投影维度 k k:8 < 303 (JL 理论下界)落入容差带的点对:345/435 (79.3%)最大失真:63.6%平均失真:19.0%

从 JL 到随机化 SVD

JL 引理保证了随机投影保持距离。但随机化 SVD 需要更强的性质:随机投影不仅要保持距离,还要捕获矩阵的主要列空间。这正是 Halko、Martinsson 和 Tropp(2011)在其里程碑论文中系统发展的理论。

关键洞察

ARm×nA \in \mathbb{R}^{m \times n} 的精确截断 SVD 为 Ak=UkΣkVkTA_k = U_k\Sigma_k V_k^T,其中 UkRm×kU_k \in \mathbb{R}^{m \times k} 的列张成了 AA 的前 kk 个左奇异向量构成的子空间。

目标:找到一个 m×km \times k(或略大)的正交矩阵 QQ,使得 QQ 的列空间近似 UkU_k 的列空间。为什么这就够了?因为 QQTQQ^T 是到 QQ 列空间的正交投影,而 Ak=UkΣkVkT=Uk(UkTA)A_k = U_k\Sigma_kV_k^T = U_k(U_k^TA) 本质上是 AAUkU_k 列空间的投影。如果两个列空间近似相同,两个投影也近似相同:QQTAUkUkTA=AkQQ^TA \approx U_kU_k^TA = A_k。一旦有了这样的 QQ,就可以在 QQ 张成的小空间里做精确 SVD。

随机投影的作用:取随机矩阵 ΩRn×(k+p)\Omega \in \mathbb{R}^{n \times (k+p)}pp 是过采样参数,通常取 5-10),计算

Y=AΩRm×(k+p)Y = A\Omega \in \mathbb{R}^{m \times (k+p)}

每一列 Yj=AωjY_j = A\boldsymbol{\omega}_jAA 列空间的一个随机采样。由于 AA 的前 kk 个奇异方向”权重最大”(奇异值 σ1σk\sigma_1 \geq \cdots \geq \sigma_k 远大于 σk+1,\sigma_{k+1}, \ldots),这些随机采样倾向于落在前 kk 个奇异方向张成的子空间附近。YY 的列空间就是我们要找的近似子空间。

Halko-Martinsson-Tropp 算法

Halko-Martinsson-Tropp 算法:两阶段流水线
阶段 1:构建近似列空间Am×nΩn×(k+p)随机Y=AΩm×(k+p)Q (QR)m×(k+p)×Q阶段 2:小空间精确分解B=QᵀA(k+p)×nSVD(B)精确 SVDU=QÛ,Σ,Vᵀ近似截断 SVD总复杂度 O(mn(k+p)),远优于全 SVD O(mn·min(m,n))

算法步骤

输入:矩阵 ARm×nA \in \mathbb{R}^{m \times n},目标秩 kk,过采样参数 pp(默认 p=5p = 51010

阶段 1——构建近似列空间

  1. 生成随机测试矩阵 ΩRn×(k+p)\Omega \in \mathbb{R}^{n \times (k+p)},元素 ΩijN(0,1)\Omega_{ij} \sim \mathcal{N}(0,1)
  2. 计算采样矩阵 Y=AΩRm×(k+p)Y = A\Omega \in \mathbb{R}^{m \times (k+p)}
  3. YY 做 QR 分解:Y=QRY = QR,取 QRm×(k+p)Q \in \mathbb{R}^{m \times (k+p)}(正交基)

阶段 2——在小空间中精确分解: 4. 计算小矩阵 B=QTAR(k+p)×nB = Q^T A \in \mathbb{R}^{(k+p) \times n} 5. 对 BB 做精确 SVD:B=U^ΣVTB = \hat{U}\Sigma V^T 6. 恢复左奇异向量:U=QU^U = Q\hat{U}

输出AUΣVTA \approx U\Sigma V^T(截断到前 kk 列即得秩 kk 近似)

逐步解读

每一步在做什么?

  • 步骤 1-2(随机采样):Y=AΩY = A\Omega 生成 AA 列空间的 k+pk+p 个随机线性组合。过采样参数 pp 的作用是提供额外的”安全余量”——即使某些随机方向碰巧与重要奇异方向正交(概率很小但非零),额外的 pp 个方向也能弥补。实践中 p=510p = 5 \sim 10 就足够了(见 Halko et al., 2011, Section 1.4)。

  • 步骤 3(QR 分解):将 YY 的列正交化,得到列空间的正交基 QQQQ 的列空间与 YY 的列空间相同,但数值上更稳定。

  • 步骤 4(换基降维):B=QTAB = Q^T AAA 的每一列从标准基换到 QQ 的列向量构成的基下,得到投影后的坐标(k+p)×n(k+p) \times n 矩阵)。严格来说投影是 QQTAQQ^TA(换基再换回),QTAQ^TA 只做了前半步——但由于后面还要在小空间里做 SVD 再用 QQ 换回(步骤 6),前半步就够了。

  • 步骤 5-6(精确 SVD + 恢复):在小空间中做精确 SVD 代价很低。U=QU^U = Q\hat{U} 把小空间中的奇异向量映射回原始空间。

伪代码

function RandomizedSVD(A, k, p=5):
    n = cols(A)
    # 阶段 1: 构建近似列空间
    Omega = randn(n, k+p)          # 随机高斯矩阵
    Y = A @ Omega                   # m × (k+p)
    Q, _ = qr(Y)                   # 正交化

    # 阶段 2: 小空间精确 SVD
    B = Q.T @ A                    # (k+p) × n
    U_hat, Sigma, Vt = svd(B)      # 精确 SVD
    U = Q @ U_hat                  # 恢复到原空间

    # 截断到秩 k
    return U[:, :k], Sigma[:k], Vt[:k, :]

幂迭代加速

幂迭代:放大奇异值间距原始σᵢσσσσσσ间距×1.31 次幂迭代σᵢ³σσσσσσ间距×2.12 次幂迭代σᵢ⁵σσσσσσ间距×3.3幂迭代将 σₖ/σₖ₊₁ 的间距从 r 放大到 r²ᵠ⁺¹ —— 使随机采样更容易区分前 k 个方向

当奇异值衰减缓慢时(即 σk\sigma_kσk+1\sigma_{k+1} 相差不大),基础算法的精度可能不够。幂迭代(power iteration)可以放大奇异值之间的差距。

思路:将步骤 2 中的 Y=AΩY = A\Omega 替换为

Y=(AAT)qAΩY = (AA^T)^q A\Omega

其中 qq 是幂迭代次数(通常 q=1q = 122 就够)。AA 的奇异值为 σi\sigma_i,则 (AAT)qA(AA^T)^q A 的奇异值为 σi2q+1\sigma_i^{2q+1}。如果原来 σk/σk+1=1.1\sigma_k / \sigma_{k+1} = 1.1,一次幂迭代后变为 (1.1)31.33(1.1)^3 \approx 1.33,两次后变为 (1.1)51.61(1.1)^5 \approx 1.61——间隔被指数级放大,随机采样更容易捕获前 kk 个方向。

复杂度分析

步骤操作复杂度
Y=AΩY = A\Omega矩阵乘法O(mn(k+p))O(mn(k+p))
Y=QRY = QRQR 分解O(m(k+p)2)O(m(k+p)^2)
B=QTAB = Q^TA矩阵乘法O(mn(k+p))O(mn(k+p))
SVD of BB精确 SVDO((k+p)2n)O((k+p)^2 n)
U=QU^U = Q\hat{U}矩阵乘法O(m(k+p)2)O(m(k+p)^2)

总计O(mn(k+p))O(mn(k+p))(矩阵乘法主导)。

与精确 SVD 对比

  • 精确全 SVD:O(mnmin(m,n))O(mn\min(m,n))
  • 截断 SVD(Lanczos/ARPACK):O(mnk)O(mnk)(但需多次 pass,且不易并行)
  • 随机化 SVD:O(mn(k+p))O(mn(k+p)),只需一次 pass(计算 Y=AΩY = A\Omega),天然适合并行和 streaming 场景

对于 Netflix 矩阵(m=480,000m = 480{,}000, n=17,000n = 17{,}000, k=50k = 50, p=10p = 10):

  • 全 SVD:1.4×1014\sim 1.4 \times 10^{14} 操作
  • 随机化 SVD:480,000×17,000×604.9×1011\sim 480{,}000 \times 17{,}000 \times 60 \approx 4.9 \times 10^{11} 操作

加速约 300 倍,且以极高概率给出几乎相同的前 50 个奇异值和奇异向量。

误差界

随机化 SVD 的理论保证来自 Halko et al.(2011, Theorem 10.5, 10.6)。

期望误差

AA 的精确截断 SVD 为 Ak=UkΣkVkTA_k = U_k\Sigma_k V_k^TEckart-Young 最佳近似),则随机化 SVD 的输出 A~k\tilde{A}_k 满足:

EAA~kF(1+kp1)1/2(j>kσj2)1/2\mathbb{E}\|A - \tilde{A}_k\|_F \leq \left(1 + \frac{k}{p-1}\right)^{1/2} \cdot \left(\sum_{j>k}\sigma_j^2\right)^{1/2}

逐项理解:

  • (j>kσj2)1/2=AAkF\left(\sum_{j>k}\sigma_j^2\right)^{1/2} = \|A - A_k\|_F 是精确截断 SVD 的误差(Eckart-Young 下界),无论什么方法都不可能比这更好
  • (1+k/(p1))1/2(1 + k/(p-1))^{1/2} 是随机化带来的额外代价因子。当 p=kp = k(过采样等于目标秩)时,这个因子约为 2\sqrt{2}——误差至多增大 41%。实践中 p=510p = 5 \sim 10 配合幂迭代即可让这个因子接近 1

Spectral 范数误差

对于谱范数(Art. 4 范数与条件数 中定义的 2\|\cdot\|_2),类似的界为:

EAA~k2(1+kp1)σk+1+ek+pp(j>kσj2)1/2\mathbb{E}\|A - \tilde{A}_k\|_2 \leq \left(1 + \sqrt{\frac{k}{p-1}}\right)\sigma_{k+1} + \frac{e\sqrt{k+p}}{p}\left(\sum_{j>k}\sigma_j^2\right)^{1/2}

当奇异值快速衰减(σk+1σk\sigma_{k+1} \ll \sigma_k)时,第一项主导,误差接近最优的 σk+1\sigma_{k+1}

直觉总结

随机化 SVD 的核心交易:用 O(mn(k+p))O(mn(k+p)) 的计算量(远低于全 SVD)换取一个(1+δ)(1+\delta) 倍最优的近似,其中 δ\delta 由过采样参数 pp 控制,且以指数概率趋于零。

数值例子

让我们用一个小例子验证算法的正确性。

AR6×4A \in \mathbb{R}^{6 \times 4} 是一个秩 2 矩阵加微弱噪声:

A=[310210][1010]σ1large+[012012][0101]σ2medium+0.01noiseσ3,σ40A = \underbrace{\begin{bmatrix}3\\1\\0\\2\\1\\0\end{bmatrix}\begin{bmatrix}1&0&1&0\end{bmatrix}}_{\sigma_1 \approx \text{large}} + \underbrace{\begin{bmatrix}0\\1\\2\\0\\1\\2\end{bmatrix}\begin{bmatrix}0&1&0&1\end{bmatrix}}_{\sigma_2 \approx \text{medium}} + \underbrace{0.01 \cdot \text{noise}}_{\sigma_3, \sigma_4 \approx 0}

假设我们只想要前 k=2k = 2 个奇异值。取 p=2p = 2,所以随机矩阵 ΩR4×4\Omega \in \mathbb{R}^{4 \times 4}

  1. 计算 Y=AΩY = A\OmegaYY6×46 \times 4 矩阵。由于 AA 几乎是秩 2 的,YY 的列几乎都落在前两个奇异向量张成的 2 维子空间内(加微弱噪声扰动)
  2. QR 分解QQ 的前两列精确捕获了这个 2 维子空间
  3. 小空间 SVDB=QTAB = Q^T A4×44 \times 4,对它做 SVD 代价极低
  4. 截断:取前 k=2k = 2 个分量,得到的 A~2\tilde{A}_2 与精确的 A2A_2 几乎相同

关键观察:AA 的前两个奇异值远大于后两个(因为构造如此),所以随机投影几乎不会”遗漏”重要方向。奇异值衰减越快,随机化 SVD 越准确。

实践要点

何时用随机化 SVD

  • 矩阵巨大但只需前 kk 个分量:这是最常见的场景。kmin(m,n)k \ll \min(m,n) 时加速最显著
  • 矩阵只能做矩阵-向量乘法(如稀疏矩阵、隐式矩阵):随机化 SVD 只需要 AΩA\OmegaATQA^T Q 两次矩阵乘法,不需要显式访问 AA 的元素
  • Streaming / single-pass:数据按行/按块到达,每次更新 YY 即可

主流实现

函数备注
scikit-learnTruncatedSVD(algorithm='randomized')默认算法
scipyscipy.sparse.linalg.svds支持稀疏矩阵
Facebook (Meta)fbpca.pca专为大规模优化
cuML (RAPIDS)cuml.decomposition.TruncatedSVDGPU 加速

scikit-learn 的 TruncatedSVDPCA 默认使用随机化 SVD(algorithm='randomized'),而非精确分解。绝大多数用户在调用 PCA(n_components=50) 时,实际执行的就是本文描述的 Halko-Martinsson-Tropp 算法。

总结与展望

本文建立了两个核心工具:

  • Johnson-Lindenstrauss 引理NN 个高维点可以被随机投影到 O(lnN/ε2)O(\ln N / \varepsilon^2) 维,同时保持所有成对距离在 (1±ε)(1 \pm \varepsilon) 以内。目标维度只取决于点数和容差,与原始维度无关——这是随机化算法的理论基石
  • 随机化 SVD(Halko-Martinsson-Tropp, 2011):通过随机投影将矩阵压缩到 k+pk + p 维子空间,再在小空间做精确 SVD。复杂度从 O(mnmin(m,n))O(mn\min(m,n)) 降到 O(mn(k+p))O(mn(k+p)),误差至多比 Eckart-Young 最优界差一个由 pp 控制的常数因子

关键公式回顾:

  • JL 维度要求k8lnN/ε2k \geq 8\ln N / \varepsilon^2
  • 随机投影f(x)=1kΩxf(\mathbf{x}) = \frac{1}{\sqrt{k}}\Omega\mathbf{x}ΩijN(0,1)\Omega_{ij} \sim \mathcal{N}(0,1)
  • 核心步骤Y=AΩQ=orth(Y)B=QTASVD(B)Y = A\Omega \to Q = \text{orth}(Y) \to B = Q^TA \to \text{SVD}(B)
  • 误差界EAA~kF(1+k/(p1))1/2AAkF\mathbb{E}\|A - \tilde{A}_k\|_F \leq (1 + k/(p-1))^{1/2}\|A - A_k\|_F

随机化 SVD 是 Part 1 “拆”阶段从精确分解走向可扩展分解的关键一步。后续的应用文章——矩阵补全NMFRobust PCA——中的大规模计算几乎都依赖随机化技术加速核心的 SVD 步骤。更远处,Part 3 “汇”中 LoRA 的低秩适配和 Efficient Attention 的低秩近似,同样植根于”大矩阵有低秩结构,可以用少量随机采样捕获”这一洞察。