SVD分解简介

• 83 min read • 16478 words
Tags: Deep Learning NLP Word2vec
Categories: NLP

本文章适用于速通SVD分解,因此讲得不是那么详细。

生成:Gemini-2.5-pro, 整理:fyerfyer

奇异值分解简介

1. 什么是 SVD?

奇异值分解(SVD)是一种强大而基础的矩阵分解技术,在数据科学、机器学习和自然语言处理(NLP)等领域有广泛应用。我们可以从三个互补的角度来理解SVD:

  1. 数据转换: SVD 能够将一组可能高度相关的变量,转换为一组线性不相关的变量。这些新的变量(或维度)可以更好地揭示原始数据项之间的内在关系。
  2. 维度排序: SVD 是一种识别和排序数据维度的方法。它会找出数据点变化最剧烈的方向(即方差最大的方向),并按重要性(方差大小)进行排序。

Σ\Sigma矩阵对角线上的奇异值 σ1σ2σ3...0\sigma_1 \geq \sigma_2 \geq \sigma_3 \geq ... ≥ 0 是严格按降序排列的。一个大的奇异值 σi\sigma_i 意味着,数据在与之对应的那个新维度(由 VV 的第 ii 个列向量和 UU 的第 ii 个列向量定义)上,有很高的方差,包含了大量的“信息”或“能量”。在我们的几何比喻中,σ1\sigma_1 对应椭圆最长的轴,σ2\sigma_2对应次长的轴。长轴显然比短轴更能定义这个椭圆的形状。

  1. 数据降维: 当我们识别出哪些维度最重要后,就可以用一个更低维度的子空间来近似表示原始数据,同时最大程度地保留原始数据的信息。因此,SVD 也是一种非常有效的数据降维(Data Reduction)方法。

2. SVD 原理

a.a. 数学分析

从数学上讲,SVD 将任意一个 m×nm \times n 的矩阵 AA 分解为三个特定矩阵的乘积:

A=UΣVTA = U\Sigma V^T

其中:

  • AA (m×nm \times n): 原始数据矩阵。在NLP中,这可以是一个“词项-文档”矩阵,其中行代表词项,列代表文档,矩阵中的值可以是词频(TF)或TF-IDF值。
  • UU (m×mm \times m): 左奇异向量矩阵。这是一个正交矩阵 (UUT=IUU^T = I)。它的列向量被称为左奇异向量,可以被看作是与原始数据相关的新基向量(例如,与“词项”相关的概念维度)。
  • Σ\Sigma (m×nm \times n): 奇异值对角矩阵。这是一个对角矩阵,其对角线上的元素 σ\sigma 被称为奇异值。这些奇异值非负,并且从大到小排列 (σ1σ20\sigma_1 \ge \sigma_2 \ge \dots \ge 0)。每个奇异值对应于一个由 UUVV 定义的新维度所包含的“能量”或“重要性”。奇异值越大,对应的维度越重要。
  • VTV^T (n×nn \times n): 右奇异向量矩阵的转置。VV 本身也是一个正交矩阵 (VVT=IVV^T = I)。它的列向量(即 VTV^T 的行向量)被称为右奇异向量,可以被看作是与原始数据相关的新基向量(例如,与“文档”相关的概念维度)。

b.b. 原理分析

构造这三个矩阵的根本原理,是为了将一个复杂、任意的线性变换(由矩阵 AA 定义),分解为三个最基本、最纯粹的几何动作:旋转、缩放、再旋转

想象一个向量 xx,当它被矩阵 AA 作用后,会变成一个新的向量 yy,即 y=Axy = Ax。这个过程 AA 可以对 xx 做任何线性的“揉捏”,比如拉伸、压缩、旋转、剪切等等,可能非常复杂。

SVD 的伟大之处在于它证明了:无论矩阵 AA 的变换有多复杂,我们总能找到一组“完美”的坐标系,让这个变换过程变得异常简单。

这三个矩阵就是实现这个目标的工具:

  1. VTV^T (第一个旋转): 改变输入空间的“视角”
    • 作用: VTV^T 是一个正交矩阵,在几何上代表一个旋转(或反射)。它首先作用于输入向量 xx
    • 原理: VV 的列向量 (v1,v2,)(v_1, v_2, \dots) 构成了一组非常特殊的正交基(互相垂直的坐标轴)。它们特殊在哪里?这些基向量是输入空间中,经过矩阵 AA 变换后,其输出结果仍然保持相互垂直的方向。
    • 比喻: 想象你在一个歪歪扭扭的房间里。VTV^T 的作用就是把你(输入向量 xx)先旋转到一个“最佳”的观察位置,让你正好对准房间的主要方向(viv_i 轴)。VTxV^Tx 的结果就是你在新坐标系下的坐标。
  2. Σ\Sigma (缩放): 在新视角下进行“拉伸”
    • 作用: Σ\Sigma 是一个对角矩阵。它的作用最纯粹:沿着新的坐标轴进行独立的缩放。
    • 原理: 当我们通过 VTV^T 把输入向量对齐到“最佳”方向 viv_i 后,Σ\Sigma 就在这些方向上进行拉伸或压缩。对角线上的奇异值 σi\sigma_i 就是对应 viv_i 方向的缩放比例。
    • 比喻: 你已经转到了最佳观察位置。现在,房间(数据空间)在你眼前的各个主方向上被拉长或缩短。σ1\sigma_1 告诉你第一个主方向被拉伸了多少倍,σ2\sigma_2 告诉你第二个主方向被拉伸了多少倍,以此类推。奇异值 σi\sigma_i 的大小,代表了 AA 变换在这个方向上的“重要性”或“能量”。
  3. UU (第二个旋转): 改变输出空间的“姿态”
    • 作用: UU 也是一个正交矩阵,代表第二次旋转。
    • 原理: 经过 VTV^T 旋转和 Σ\Sigma 缩放后,我们得到了一个位于输出空间中的向量,但它的坐标是基于 UU 的列向量 (u1,u2,)(u_1, u_2, \dots) 这个“最佳”输出基准的。UU 的列向量 uiu_i 正是输入基 viv_i 经过 AA 变换后的方向 (Avi=σiuiAv_i = \sigma_i u_i)。UU 的作用就是将这个结果从 uiu_i 坐标系旋转回我们通常使用的标准坐标系(比如 x-y-z 坐标系)。
    • 比喻: 房间被拉伸后,你看到了一个变形后的结果。UU 的作用就是把这个变形后的结果摆正,让你从一个标准的、正前方的角度看到最终的成品。

总结一下这个过程:

y=UΣVTxy = U \Sigma V^T x
  1. VTxV^T x: 拿来一个向量 xx,先把它旋转到输入空间的一组“黄金”正交基 VV 上。
  2. Σ(VTx)\Sigma(V^T x): 在这个“黄金”基的每个轴上,对向量的相应分量进行缩放(拉伸或压缩)。
  3. U(Σ(VTx))U(\Sigma(V^T x)): 将缩放后的结果,通过另一次旋转,摆到输出空间的最终位置。

这种分解方式揭示了矩阵 AA 最本质的特性:

  • 降维和数据压缩: 奇异值 σ\sigma 是从大到小排列的。很多时候,只有前几个 σ\sigma 值非常大,后面的都很小甚至接近于零。这意味着 AA 的变换主要发生在少数几个方向上。我们可以只保留最大的 kk 个奇异值以及对应的 UUVV 中的向量,构造一个近似矩阵 AA'
A=UkΣkVkTA' = U_k \Sigma_k V_k^T

这个 AA' 用更少的数据(knk \ll n)就能高度近似原始矩阵 AA,这就是降维的核心,也是 LSA (Latent Semantic Analysis) 在 NLP 中提取“潜在语义”的数学基础。

  • 揭示数据结构: VV 的列向量指出了输入数据中最重要的“模式”方向,UU 的列向量指出了输出数据中最重要的“模式”方向,而 Σ\Sigma 则量化了每种模式的重要性。
  • 数值稳定性: 在数值计算中,SVD 是最稳健的矩阵分解方法之一,可以用来求解线性方程组、计算伪逆等,即使矩阵是奇异的或病态的(ill-conditioned)。

3. SVD 在 NLP 中的应用

在NLP应用中,直接处理高维稀疏的“词项-文档”矩阵通常效果不佳。SVD 提供了一种强大的解决方案,最经典的应用就是潜在语义分析 (Latent Semantic Analysis, LSA 或 LSI)

  • 在LSA中,SVD被用来分解“词项-文档”矩阵。
  • 分解后的 UU 矩阵将词项映射到一个低维的“语义空间”中。
  • VV 矩阵将文档也映射到同一个语义空间中。
  • 在这个低维空间里,我们可以计算词与词、文档与文档、或者词与文档之间的相似度。由于降维过程去除了“噪声”并捕捉了“潜在”的语义关系,即使两个文档没有共享任何相同的词,只要它们在语义上相关(例如,都讨论“汽车”和“引擎”),它们在语义空间中的表示也会很接近。

这使得SVD在信息检索、文档聚类、文本分类等任务中非常实用。你可以忽略掉那些奇异值非常小的维度(通常被视为噪声),从而大大减少计算量,同时还能提升任务的准确性。

好的,这是更新后的版本,其中代码框内的矩阵也已替换为 LaTeX 格式:

4. SVD 计算实例与应用解析

下面我们将将通过一个完整的计算例子,展示如何手动进行SVD,并进一步探讨其在数据降维中的应用。

a.a. SVD前情提要

线性代数中的一个基本定理指出:任何一个 m×nm \times n 的矩阵 AA 都可以被分解为三个矩阵的乘积:一个正交矩阵 UU、一个对角矩阵 SS 和另一个正交矩阵 VV 的转置 VTV^T

A(m×n)=U(m×m)S(m×n)VT(n×n)A (m \times n) = U (m \times m) S (m \times n) V^T (n \times n)

  • UUVV 都是正交矩阵,满足 UTU=IU^TU = I, VTV=IV^TV = I
  • UU 的列向量是 AATAA^T 的正交特征向量。
  • VV 的列向量是 ATAA^TA 的正交特征向量。
  • SS 是一个对角矩阵,其对角线上的值(奇异值)是 AATAA^TATAA^TA 的特征值的平方根,并按降序排列。

b.b.例子展示

我们将为以下 2x3 矩阵 AA 计算其完整的SVD:

A=(311131)A = \begin{pmatrix} 3 & 1 & 1 \\ -1 & 3 & 1 \end{pmatrix}
i.i. 计算 UU (左奇异向量)

UU 的列向量来自于 AATAA^T 的特征向量。

1 计算 AA 的转置 ATA^T

AT=(311311)A^T = \begin{pmatrix} 3 & -1 \\ 1 & 3 \\ 1 & 1 \end{pmatrix}

2 计算 AATAA^T

AAT=(311131)(311311)=(111111)AA^T = \begin{pmatrix} 3 & 1 & 1 \\ -1 & 3 & 1 \end{pmatrix} \begin{pmatrix} 3 & -1 \\ 1 & 3 \\ 1 & 1 \end{pmatrix} = \begin{pmatrix} 11 & 1 \\ 1 & 11 \end{pmatrix}

3 计算 AATAA^T 的特征值 (Eigenvalues)

我们需要求解方程 (AATλI)v=0(AA^T - \lambda I)v = 0 的非零解 vv。这需要 det(AATλI)=0det(AA^T - \lambda I) = 0

det11λ1111λ=(11λ)(11λ)11=0\det \begin{vmatrix} 11-\lambda & 1 \\ 1 & 11-\lambda \end{vmatrix} = (11-\lambda)(11-\lambda) - 1 \cdot 1 = 0

展开后得到 λ222λ+120=0\lambda^2 - 22\lambda + 120 = 0,分解为 (λ10)(λ12)=0(\lambda - 10)(\lambda - 12) = 0。 所以,我们得到两个特征值:λ1=12,λ2=10\lambda_1 = 12, \lambda_2 = 10

4 计算 AATAA^T 的特征向量 (Eigenvectors)

  • 对于 λ1=12\lambda_1 = 12: (1112)x1+x2=0    x1+x2=0    x1=x2(11-12)x_1 + x_2 = 0 \implies -x_1 + x_2 = 0 \implies x_1 = x_2 我们可以选择一个简单的特征向量,如 [1,1][1, 1]
  • 对于 λ2=10\lambda_2 = 10: (1110)x1+x2=0    x1+x2=0    x1=x2(11-10)x_1 + x_2 = 0 \implies x_1 + x_2 = 0 \implies x_1 = -x_2 我们可以选择特征向量 [1,1][1, -1]

5 构建并规范化 UU

我们将特征向量作为列,并按特征值从大到小的顺序排列,得到矩阵 [v1,v2][v_1, v_2]

(1111)\begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix}

为了得到正交矩阵 UU,我们需要对这些列向量进行规范化(使其长度为1)。

  • u1=v1/v1=[1,1]/12+12=[1/2,1/2]u_1 = v_1 / ||v_1|| = [1, 1] / \sqrt{1^2+1^2} = [1/\sqrt{2}, 1/\sqrt{2}]
  • u2=v2/v2=[1,1]/12+(1)2=[1/2,1/2]u_2 = v_2 / ||v_2|| = [1, -1] / \sqrt{1^2+(-1)^2} = [1/\sqrt{2}, -1/\sqrt{2}]

所以,我们得到了 UU 矩阵:

U=(1/21/21/21/2)U = \begin{pmatrix} 1/\sqrt{2} & 1/\sqrt{2} \\ 1/\sqrt{2} & -1/\sqrt{2} \end{pmatrix}
ii.ii. 计算 VV (右奇异向量)

VV 的列向量来自于 ATAA^TA 的特征向量。

1 计算 ATAA^TA

ATA=(311311)(311131)=(10020104242)A^TA = \begin{pmatrix} 3 & -1 \\ 1 & 3 \\ 1 & 1 \end{pmatrix} \begin{pmatrix} 3 & 1 & 1 \\ -1 & 3 & 1 \end{pmatrix} = \begin{pmatrix} 10 & 0 & 2 \\ 0 & 10 & 4 \\ 2 & 4 & 2 \end{pmatrix}

2 计算 ATAA^TA 的特征值

同样,我们求解 det(ATAλI)=0det(A^TA - \lambda I) = 0

det10λ02010λ4242λ==λ(λ10)(λ12)=0\det \begin{vmatrix} 10-\lambda & 0 & 2 \\ 0 & 10-\lambda & 4 \\ 2 & 4 & 2-\lambda \end{vmatrix} = \dots = \lambda(\lambda-10)(\lambda-12) = 0

我们得到三个特征值:λ1=12,λ2=10,λ3=0\lambda_1 = 12, \lambda_2 = 10, \lambda_3 = 0。(注意:非零特征值与 AATAA^T 的特征值相同)

3 计算 ATAA^TA 的特征向量

通过将每个特征值代入 (ATAλI)v=0(A^TA - \lambda I)v = 0,我们可以解得对应的特征向量:

  • 对于 λ1=12\lambda_1 = 12, v1=[1,2,1]v_1 = [1, 2, 1]
  • 对于 λ2=10\lambda_2 = 10, v2=[2,1,0]v_2 = [2, -1, 0]
  • 对于 λ3=0\lambda_3 = 0, v3=[1,2,5]v_3 = [1, 2, -5]

4 构建并规范化 VV

将特征向量按顺序 [v1,v2,v3][v_1, v_2, v_3] 排列并进行规范化:

  • u1=v1/v1=[1,2,1]/6=[1/6,2/6,1/6]u_1 = v_1 / ||v_1|| = [1, 2, 1] / \sqrt{6} = [1/\sqrt{6}, 2/\sqrt{6}, 1/\sqrt{6}]
  • u2=v2/v2=[2,1,0]/5=[2/5,1/5,0]u_2 = v_2 / ||v_2|| = [2, -1, 0] / \sqrt{5} = [2/\sqrt{5}, -1/\sqrt{5}, 0]
  • u3=v3/v3=[1,2,5]/30=[1/30,2/30,5/30]u_3 = v_3 / ||v_3|| = [1, 2, -5] / \sqrt{30} = [1/\sqrt{30}, 2/\sqrt{30}, -5/\sqrt{30}]

所以,我们得到了 VV 矩阵:

V=(1/62/51/302/61/52/301/605/30)V = \begin{pmatrix} 1/\sqrt{6} & 2/\sqrt{5} & 1/\sqrt{30} \\ 2/\sqrt{6} & -1/\sqrt{5} & 2/\sqrt{30} \\ 1/\sqrt{6} & 0 & -5/\sqrt{30} \end{pmatrix}
iiiiii 计算 SS (奇异值矩阵)

SS 的对角线元素是奇异值,即非零特征值的平方根。

  • σ1=12\sigma_1 = \sqrt{12}
  • σ2=10\sigma_2 = \sqrt{10}

SS 的维度需要是 m×nm \times n (即 2x3),所以我们需要用0来填充。

S=(12000100)S = \begin{pmatrix} \sqrt{12} & 0 & 0 \\ 0 & \sqrt{10} & 0 \end{pmatrix}
iv.iv. 整合与验证

现在我们把 UU, SS, VTV^T 乘起来:

A=USVTA = U S V^T VT=(1/62/61/62/51/501/302/305/30)V^T = \begin{pmatrix} 1/\sqrt{6} & 2/\sqrt{6} & 1/\sqrt{6} \\ 2/\sqrt{5} & -1/\sqrt{5} & 0 \\ 1/\sqrt{30} & 2/\sqrt{30} & -5/\sqrt{30} \end{pmatrix} A=(1/21/21/21/2)(12000100)(1/62/61/62/51/501/302/305/30)A = \begin{pmatrix} 1/\sqrt{2} & 1/\sqrt{2} \\ 1/\sqrt{2} & -1/\sqrt{2} \end{pmatrix} \begin{pmatrix} \sqrt{12} & 0 & 0 \\ 0 & \sqrt{10} & 0 \end{pmatrix} \begin{pmatrix} 1/\sqrt{6} & 2/\sqrt{6} & 1/\sqrt{6} \\ 2/\sqrt{5} & -1/\sqrt{5} & 0 \\ 1/\sqrt{30} & 2/\sqrt{30} & -5/\sqrt{30} \end{pmatrix}

经过矩阵乘法运算,最终结果会精确地等于原始矩阵 AA

A=(311131)A = \begin{pmatrix} 3 & 1 & 1 \\ -1 & 3 & 1 \end{pmatrix}

这完成了完整的SVD分解。

c.c. 降维 SVD (Reduced SVD)

在实际应用中,我们通常不关心对原始矩阵的精确重建,而是希望利用SVD来降维去噪。这就是降维SVD(或称截断SVD)的用武之地。

奇异值 SS 从大到小排列,代表了数据在各个新维度上的重要性。通常,前几个最大的奇异值就包含了数据的绝大部分信息,而后面的小奇异值多半对应于数据中的“噪声”。

因此,我们可以通过只保留前 kk 个最大的奇异值和对应的左右奇异向量来近似原始矩阵:

AAk=UkSkVkTA \approx A_k = U_k S_k V_k^T

  • UkU_k: UU 的前 kk
  • SkS_k: SS 的前 k×kk \times k 部分
  • VkTV_k^T: VTV^T 的前 kk

降维SVD是潜在语义索引/分析 (LSI/LSA) 背后的核心技术。LSA通过SVD来分析“词项-文档”矩阵,发掘词项和文档之间潜在的语义关系。

1. 原始数据 假设我们有一个“词项 x 文档”矩阵 AA,矩阵的值代表词项在文档中的重要性(如TF-IDF)。

2. SVD 分解与降维 我们对 AA 进行SVD分解,并选择一个合适的 kk(比如 k=2k=2k=3k=3)来进行降维,得到 UkU_k, SkS_k, VkV_k

3. 语义空间

  • UkU_k 的行向量代表了每个词项kk 维“语义空间”中的坐标。
  • VkV_k 的行向量(即 VkTV_k^T 的列向量)代表了每个文档在同一个 kk 维“语义空间”中的坐标。

4. 发现相似性 在这个低维的语义空间中,我们可以:

  • 通过计算 UkU_k 中行向量之间的余弦相似度,来找到语义上相近的词。
  • 通过计算 VkV_k 中行向量之间的余弦相似度,来找到内容上相似的文档。

关键优势: 降维过程清除了噪声,并使得原本没有共享词汇但主题相似的文档在语义空间中变得更加接近。例如,一篇关于“汽车”的文档和一篇关于“发动机”的文档,在降维后的空间中可能会有很高的相似度。