Courses
您是否曾尝试从包含上千个特征的数据集中提取有用模式?
您知道,一个庞大的数据集中一定埋藏着某种有用的结构。问题在于,原始数据集往往包含大量噪声、冗余、缺失值,以及远超实际所需的维度。大多数机器学习算法要么难以理解这类数据,要么在最好的情况下也会大幅拖慢训练时间。
奇异值分解(SVD)将任意矩阵(此处即数据集)拆分为三个更简单的矩阵,进而展示其核心结构。它是推荐系统、图像压缩以及 PCA 等降维技术背后的数学基础——一旦您理解了它,您会在日常工作中处处看到它的身影。
本文将带您了解什么是 SVD、其工作原理、在数据科学中的应用场景,以及在何种情况下应当选择替代方法。
觉得向量、行列式等概念让人困惑?在继续阅读本文之前,请先查阅我们的《深度学习中的数学概念解惑》一文。
什么是奇异值分解(SVD)?
SVD 是一种将任意矩阵拆分为三个更简单矩阵的方法。
可以这样理解。您有一个矩阵 A ——它可以是一个数据集或一张图像。SVD 将 A 拆成三部分:

SVD 公式
-
U是一个m x m的正交矩阵。其列向量称为左奇异向量,用于描述A的各行之间的关系 -
\Sigma是一个m x n的对角矩阵。对角线上的值称为奇异值——总是非负,并按从大到小排序 -
V*是一个n x n正交矩阵的共轭转置。其行向量称为右奇异向量,用于描述 A 的各列之间的关系
每个部分都展示了原始数据的不同侧面。U 包含行层面的模式(行与行如何相关),\Sigma 包含重要性权重(各模式的重要程度),而 V* 包含列层面的模式(列与列如何相关)。
打个比方。假设您要向他人描述一道菜谱。您可以将其分成三部分:食材(用什么)、配比(各用多少)和步骤(如何组合)。这三部分单独看都无法还原整道菜,但合在一起便提供了所需的一切信息。SVD 对矩阵做的就是同样的事——它把“是什么”“有多少”“如何做”拆成相互独立、可分别处理的组成部分。
在线性代数中,SVD 的突出之处在于它适用于任意矩形矩阵。它不要求矩阵是方阵,也不需要具备特殊性质。任何 m x n 的矩阵都可以这样分解,这也就是它在数据科学中无处不在的原因。
SVD 的实战机制
我们从头开始,仔细看看 SVD 如何工作。
解释矩阵分解
假设您有一个 3×2 的矩阵 A:

矩阵分解
SVD 将其分解为 U(3×3)、\Sigma(3×2)和 V*(2×2)。U 的列来自 A x A^T 的特征向量,而 V 的列来自 A^T x A 的特征向量。\Sigma 中的奇异值是这两个乘积的特征值的平方根。
好消息是,您无需手工计算。在 Python 中,只需一行代码:
import numpy as np
A = np.array([[1, 2], [3, 4], [5, 6]])
U, sigma, Vt = np.linalg.svd(A, full_matrices=True)

Numpy 输出
这三个矩阵通过相乘相互作用。U 在行空间中旋转数据,\Sigma 沿各轴缩放,V* 在列空间中旋转。结果就是原始矩阵 A。
奇异值的作用
在 \Sigma 的对角线上,数值告诉您各个成分对整体矩阵的贡献程度。
第一个奇异值总是最大——它捕捉数据中最主导的模式。之后的每个值所捕捉的信息更少。若前几个奇异值很大,其余接近于零,则意味着矩阵中的大部分信息集中在少数几个成分中。
这正是实现数据压缩的关键。
您可以舍弃较小的奇异值(以及在 U 中与之对应的列、在 V* 中与之对应的行),而不会损失太多信息。由此得到原矩阵的一个低秩近似,规模更小、处理更快。
非零奇异值的数量也揭示了矩阵的秩——即线性无关的行或列的数量。若一个 100×50 的矩阵只有 10 个非零奇异值,意味着数据只有 10 个独立维度,另外 40 个是冗余的。
重构矩阵
您可以通过将三部分相乘,重建原始矩阵:

矩阵重构
但您真正想要的是部分重构。因此,与其使用全部奇异值,不如只保留前 k 个值及其对应向量。这将得到 秩为 k 的近似矩阵 A:

秩-k 矩阵近似
Eckart-Young 定理保证该秩-k 近似是在 Frobenius 范数意义下最接近原矩阵 A 的秩为 k 的矩阵。换言之,如果您要将矩阵压缩到 k 个维度,SVD 能给出最优结果。
SVD 在数据科学中的应用
一旦开始留意,您会发现 SVD 出现的频率远超预期。
思路始终如一:拿到一个大矩阵,保留重要部分,去掉其余。不同之处在于,何为“重要”,取决于具体问题。
降维
高维数据集既难处理又难解释。特征越多,训练时间越长,过拟合风险越高。SVD 通过减少维度数量来避免这些问题。
大体流程是这样的:分解数据矩阵,观察奇异值,只保留前 k 个成分。较小的奇异值代表噪声和次要变化,移除它们几乎不会影响数据质量。最终得到的表示更紧凑,但仍保留了大部分原始结构。
这正是主成分分析(PCA)的工作方式。PCA 先对数据中心化,然后对结果做 SVD。主成分对应右奇异向量,而奇异值则告诉您各成分能解释多少方差。
推荐系统
Netflix 和 Amazon 之类的公司拥有海量的用户-物品矩阵,其中大多数条目为空。用户只会在成千上万部影片中评几个分,因此该矩阵是稀疏的。SVD 可以用来填补空白。
思路是将评分矩阵分解为用户偏好与物品特征。U 表示每位用户在意的因素(类型、节奏、风格),V* 则表示每个物品所具备的属性。\Sigma 中的奇异值按重要程度对这些因素进行缩放。将它们相乘后,就能得到用户尚未观看影片的预测评分。
在实践中,标准 SVD 不能直接用于稀疏矩阵,因为它会把缺失值当作零处理。因此系统会采用诸如截断 SVD或矩阵分解等只在已观测条目上操作的方法的变体。
图像压缩
灰度图像就是像素值构成的矩阵。SVD 可以通过只保留最重要的奇异值来压缩它。
假设您有一张 1000×1000 的图片。完整 SVD 会给出 1000 个奇异值。但如果您只保留前 50 个,就可以用 50 个成分而非 1000 个来重构图像。图像会略显模糊,但仍可辨识——而存储量将从 1,000,000 个数降至约 100,500 个(U 的 50 列 + 50 个奇异值 + V* 的 50 行)。
保留的奇异值越多,图像质量越好,但压缩率越低;保留越少,文件更小,但损失更大。您可以根据具体使用场景自行权衡。
性能考量与局限
矩阵越大,计算成本就越高。
计算成本
对一个 m x n 的矩阵做完整 SVD,其时间复杂度为O(mn²)(假定 m >= n)。对于小矩阵问题不大,但若矩阵拥有数百万行与成千上万列,代价就会非常高。
内存也是瓶颈之一。完整 SVD 会产生三个稠密矩阵,同时存储可能会超出可用内存。
解决办法是在不需要时避免计算完整 SVD。截断 SVD 只计算前 k 个奇异值及其向量,速度快得多。在 Python 中,scipy.sparse.linalg.svds 和 sklearn.decomposition.TruncatedSVD 都可实现该方法。随机化 SVD 进一步利用随机采样近似分解,在只需主导成分时效果良好。
稳定性与准确性
SVD 在大多数情况下数值稳定,但在某些数据模式下会遇到困难。
高噪声数据就是一例。如果信噪比较低,最大的奇异值无法与噪声明显分离。此时在近似时要么会保留噪声,要么在截断时削弱信号。
病态矩阵也是问题之一。当最大与最小奇异值的比值巨大(条件数高)时,计算中的细小数值误差会被放大。这可能导致结果不可靠,尤其是在浮点精度受限时。
应对方法是在截断前先检查奇异值。绘图观察信号与噪声之间是否存在明显的“断崖”。若衰减平缓、没有清晰的拐点,SVD 或许并非该数据集的最佳工具。
SVD 的替代方案
SVD 不是唯一的矩阵分解方法,也并非每个任务的最佳选择。
下面列出的每种替代方法都针对特定类型的问题。它们并非 SVD 的替身,因为各自基于不同的假设与约束。正确的选择,始终取决于您要完成的任务。
特征分解
特征分解 与 SVD 最为接近。它将方阵分解为特征值与特征向量:

特征分解公式
其中 Q 包含特征向量,\Lambda 为特征值构成的对角矩阵。
问题在于它只适用于方阵。若您的数据矩阵是 m x n 且 m != n,特征分解无法直接处理。SVD 适用于任意形状矩阵,因此更通用。
对于方阵、对称矩阵(如协方差矩阵),特征分解与 SVD 的结果密切相关。对称正半定矩阵的奇异值就是其特征值。因此,当您在 PCA 中处理协方差矩阵时,两种方法得到的结果一致。SVD 只是能推广到非方阵情形的版本。
QR 分解
QR 分解 将矩阵拆分为正交矩阵 Q 与上三角矩阵 R:

QR 分解公式
在某些任务上,它比 SVD 更快,尤其是在求解线性方程组与最小二乘问题时。
代价在于信息量。QR 不提供奇异值,因此无法告诉您矩阵的秩,或哪些成分权重更大。若您只是需要求解 Ax = b,而不关心底层结构,QR 是不错的选择;但如果需要理解或压缩数据,SVD 更合适。
非负矩阵分解(NMF)
NMF 将一个矩阵分解为两个所有元素均非负的矩阵:

NMF 公式
这一约束使 NMF 非常适合本质上非负的数据(如像素强度或词频)。相较之下,SVD 不强制非负,其分解所得矩阵可能包含负值,有时会导致成分难以解释。
NMF 在文本挖掘与主题建模中尤为流行。W 的每一列可代表一个主题,H 的每一行展示该主题在各文档中的占比。非负约束意味着主题由词语的加性组合构成,相比 SVD 带有正负混合符号的成分,更易于解读。
不足在于 NMF 不保证解的唯一性,且结果依赖初始化。SVD 对同一输入始终产生相同输出。
随机化 SVD
如果矩阵过大无法做完整 SVD,但您仍然需要奇异值,随机化 SVD 值得一试。它使用随机投影来近似前 k 个奇异值及其向量,而无需计算完整分解。诸如 scikit-learn(TruncatedSVD)和 Facebook 的 fbpca 等库实现了这种方法,且能很好地扩展到拥有数百万行的矩阵。
下表总结了各方法的适用场景。

SVD 的替代方案
使用 SVD 的其他注意事项
有几个常见问题容易让新入行的数据科学家困惑。
其一是误读奇异值。较大的奇异值意味着该成分能解释数据中的大量方差——并不代表该成分在特定领域语义上“重要”。例如,用户评分矩阵中的主导奇异值可能仅仅反映“多数人都会给热门影片打分”这一事实,而非任何有意义的偏好模式。务必在数据语境中解读奇异值,而非只看其数值大小。
其二是不必要时仍然使用 SVD。在小数据集(数百行、少量列)上,SVD 只会增加不必要的复杂性。简单的方法,如相关性分析或基础特征筛选,往往更快且代码更少。SVD 在高维且具冗余结构的数据上表现出色——若您的数据集不符合这一定义,优先选择更简单的方法。
结语
SVD 将任意矩阵拆成三个展示其结构的组成部分。奇异值告诉您数据中哪些部分最为关键,左右奇异向量则展示了其背后的行、列模式。
这种分解支撑着许多日常使用的实用工具。推荐系统用它来预测缺失评分;图像压缩用它在保持视觉质量的同时减少文件大小。尽管领域不同,它们背后的数学几乎相同。
但 SVD 并非总是正确工具。对于大矩阵,它代价高昂;当奇异值缺乏清晰分离时,容易将信号与噪声混杂;对小数据集而言也显得小题大做。QR 分解、特征分解与 NMF 等替代方案在特定情形下更胜一筹。
关键在于,知道何时应使用 SVD,何时更简单的方法更合适。要系统掌握这类判断,请报名我们的Python 机器学习科学家学习路径,在 2026 年做好上岗准备。
SVD 常见问答
什么是奇异值分解(SVD)?
SVD 是一种矩阵分解方法,将任意矩阵拆分为三个组成部分:左奇异向量(U)、奇异值(Σ)和右奇异向量(V*)。无论矩阵的形状与大小如何,SVD 都适用。SVD 通过将数据拆分为模式及其相对重要性来揭示数据的底层结构。
为什么在数据科学和机器学习中使用 SVD?
SVD 有助于在高维数据集中减少维度数量,同时保留最重要的模式。它是 PCA 和推荐系统背后的数学基础。这些应用都依赖同一个理念:保留主导成分,移除其余部分。
SVD 与特征分解有何不同?
特征分解只适用于方阵,而 SVD 适用于任意形状的矩阵。对于如协方差矩阵这类方阵、对称矩阵,两种方法的结果密切相关——正半定矩阵的奇异值就是其特征值。SVD 更通用,这也是它在多数数据科学工作流中成为默认选择的原因。
奇异值与数据压缩有何关系?
奇异值按从大到小排序,每个值表示某个成分能解释的方差大小。移除较小的奇异值(及其对应向量)会去除次要模式与噪声,同时保留主导结构。这样会以小幅精度损失换取大幅的规模压缩。
何时应避免使用 SVD?
在大矩阵上,完整 SVD 的计算代价高,时间复杂度为 O(mn^2)。对于只有少数特征的小型数据集,更简单的方法(如相关性分析或基础特征选择)往往更快。如果矩阵很大且您只需要前若干成分,截断或随机化 SVD 比完整 SVD 更合适。