☰
【第61期】NumPy SVD 低秩重构:矩形矩阵、截断误差与错误形状排查完整教程
2026/10/25 1:56:19 网站建设 项目流程

系列:《从小白到 AI 大模型开发工程师的进阶之路》 技术点:AI-0215 奇异值分解 主人公:小蓝伞 前置:AI-0213 矩阵运算;建议先读第60期特征值与特征向量 本期产出:一个能报告各截断秩误差、验证满秩重构并拒绝一维输入的实验脚本

小蓝伞准备把一张矩阵“压瘦”,却遇到两个疑问:矩形矩阵没有普通的方阵特征分解形式,怎样拆;只留下最大的几个分量,损失究竟是多少?这是教学情境,不是生产事故。本文用一份手工构造的四行三列矩阵跑通 SVD、低秩重构和输入失败验证。实测保留两个分量时相对残差约为百分之六点八二,保留全部三个分量时达到浮点精度内的重构。读者得到的是明确的误差口径和可复制程序,而不是“压缩一定提升预测效果”的承诺。

一、小蓝伞遇到的问题

输入矩阵有四行三列,行可理解为四个观测,列可理解为三个数值字段。但本例只用来验证线性代数,不给列附会业务意义。矩阵第三行全为零,其他行中既有对角结构也有交叉项,因此并非简单地删除某一列就能得到最佳低秩表达。

小蓝伞最初想直接取最大的特征值。排查前先检查形状:特征方程要求同一空间中的方阵作用,本例的输入、输出空间维数不同。换用 SVD 后,程序能分解矩形矩阵,接下来需要验证三个问题:输出形状是否匹配;截断的分量是否按降序选择;误差是绝对残差还是相对残差。缺任何一项,都可能出现“代码能跑,说明说错了”的情况。

二、先给结论

实数矩阵可以写成三部分相乘:左奇异向量、奇异值对角矩阵、右奇异向量的转置。用 NumPy 的紧凑输出完成低秩重构时,正确式子是先截取对应列和行,再乘回原形状。

  1. 本例采用full_matrices=False,避免生成重构不需要的额外正交方向。

  2. 奇异值按降序排列,截断保留前几个分量;奇异值数量上限是行列数中的较小值。

  3. 用 Frobenius 范数衡量全部元素的联合残差,同时报告相对残差。

  4. 零矩阵可以重构,但相对误差的分母为零,不能直接相除后把无效结果当成准确率。

  5. 一维输入在本篇封装中明确拒绝。NumPy 支持更高维批量 SVD,本例没有扩展到该接口。

  6. 重构误差下降只证明当前矩阵保存得更完整,不证明推荐、分类或预测一定更准确。

三、本文要解决什么

项目本期约定
输入手工构造的实数二维矩阵,不含缺失值
输出奇异值、各秩绝对残差、各秩相对残差
环境Windows 11、Python 3.13.9、NumPy 2.3.5
成功判据满秩重构接近原矩阵;截断误差随秩增加而不增加
失败判据一维数组不能进入二维重构接口;秩不得越界
不在范围大规模稀疏求解、性能排名、真实推荐评测

四、前置准备

使用独立练习目录,下面路径仅为建议,可以替换成自己的目录。程序不覆盖已有数据,不需要管理员权限。依赖安装需要正常访问包源;本地已有对应版本时直接使用即可。

New-Item -ItemType Directory -Force D:\ai-learning\issue-61 Set-Location D:\ai-learning\issue-61 python -m venv .venv .\.venv\Scripts\python.exe -m pip install numpy==2.3.5 .\.venv\Scripts\python.exe --version .\.venv\Scripts\python.exe -c "import numpy; print(numpy.__version__)"

这些新建环境步骤是读者复现步骤,本次运行使用现有 Python 环境,未宣称重新安装过依赖。不必激活环境,显式调用其中的解释器可以减少终端混用风险。若安装受网络或版本兼容条件限制,先记录错误并核对官方支持范围,不随意更换来源或扩大安装权限。

五、核心原理

从矩阵变换理解分解

对一个有四行三列的实数矩阵,紧凑 SVD 给出:左因子四行三列,奇异值向量长度三,右转置因子三行三列。奇异值向量不能直接当成二维矩阵使用;可以构造对角矩阵,也可以通过广播将左因子的每一列乘上对应奇异值。然后乘右转置因子,结果仍是四行三列。

本地 NumPy 2.3.5 官方函数说明给出的重构约定是u @ np.diag(s) @ vh,等价于(u * s) @ vh。本篇变量名用vt表示实数情形的转置。若将来处理复数,接口返回的是共轭转置,应把这个区别保留下来,不能机械使用普通转置。

截断不是删掉某几个原始字段

截断保留的是分量方向,不是原始列名单。每个分量都由一个左方向、一个伸缩量和一个右方向共同组成。取前两个分量时,截取左因子的前两列、奇异值前两项和右因子的前两行,三者必须同时变化。只截奇异值而不改其他因子,会造成形状错误。

错误认知是“第一奇异值最大,所以第一个业务字段最重要”。正确认知是“大奇异值对应一个更强的矩阵变换方向”。这个方向可能由多个字段组合而成,而且会受到原始尺度影响。若金额用元、时间用秒,不能跳过单位说明就给字段排业务价值。

怎样给误差一个可核对的定义

绝对残差是所有元素差值平方求和,再开平方,也就是 Frobenius 范数。相对残差是绝对残差除以原矩阵的同一范数。因此“保留两个分量后误差百分之六点八二”指整个矩阵的相对范数残差,不能解释为“每个元素都错百分之六点八二”,更不能解释为分类错误率。

也可以报告保留能量比例,即保留奇异值平方和除以全部平方和。它和相对残差有关,但不是同一个数字:保留能量高,并不意味着相对残差按相同比例降低。选择指标时应先决定要限制残差、保留能量还是下游任务损失,再计算对应口径。

六、完整实践

目录只需要一个main.py。数据由代码直接构造,无需下载图片或读取上一期文件。将以下完整代码保存为 UTF-8:

import numpy as np ​ ​ def reconstruct(matrix: np.ndarray, rank: int) -> np.ndarray: """按指定截断秩重构矩阵,并显式检查输入边界。""" if matrix.ndim != 2: raise ValueError("matrix 必须是二维数组") u, singular_values, vt = np.linalg.svd(matrix, full_matrices=False) if not 0 <= rank <= singular_values.size: raise ValueError("rank 必须位于 0 到 min(m, n) 之间") if rank == 0: return np.zeros_like(matrix) return (u[:, :rank] * singular_values[:rank]) @ vt[:rank, :] ​ ​ matrix = np.array( [[3.0, 0.0, 1.0], [0.0, 2.0, 0.0], [0.0, 0.0, 0.0], [1.0, 1.0, 0.0]], dtype=np.float64, ) u, singular_values, vt = np.linalg.svd(matrix, full_matrices=False) print("shape", matrix.shape, "singular", np.round(singular_values, 6).tolist()) for rank in range(singular_values.size + 1): restored = reconstruct(matrix, rank) residual = np.linalg.norm(matrix - restored, ord="fro") relative = residual / np.linalg.norm(matrix, ord="fro") print("rank", rank, "residual", round(float(residual), 8), "relative", round(float(relative), 8)) ​ try: reconstruct(np.array([1.0, 2.0]), 1) except ValueError as exc: print("invalid", type(exc).__name__, str(exc))

在练习目录运行:

.\.venv\Scripts\python.exe main.py

成功时会输出矩阵形状、三个奇异值、四种截断秩和最后的一维输入错误。本次实际数字见下一节。这里显式捕获异常仅用于展示失败样本,不是生产中吞掉异常的建议;业务调用应根据契约选择向上传递或转换为可定位错误。

七、可复现失败案例

故意把二维矩阵替换为一维数组,直接调用 NumPy SVD 时得到“数组至少必须二维”的线性代数异常。影响是调用方无法区分“维度输入错误”和“算法未收敛”。最初误判可能是某个数值不适合求解,但检查形状后就能定位原因:维度已经在进入算法前失效。

修复是在封装入口判断维度,并抛出明确的ValueError。原一维失败样本重新运行后输出“matrix 必须是二维数组”,正常矩阵仍能生成全部误差行,构成一条可复验的修复链。不要为了消除报错自动把任意一维输入重塑成矩阵;一行样本和一列样本含义不同,应由调用者决定。

另一个建议验证的边界是非法秩。把秩改为负数或超过三,应得到越界异常,而不是静默得到少量分量。当前函数约定调用者传入整数秩,若要作为公共接口,还需要拒绝布尔值、小数、空维度和非有限元素,并给这些输入补运行记录;本期没有冒称这些扩展全部执行完成。

八、实验设计与数据

本次是确定性功能实验,不是计时基准。固定四行三列输入、双精度类型和依赖版本,仅改变截断秩。正常样本、零秩边界、满秩边界和一维失败样本均在本机执行。奇异值约为三点三二五六一一、二点二零五八九八和零点二七二六三零。

截断秩绝对残差相对残差
04.00000000100.0000%
12.2226818855.5670%
20.272629666.8157%
3打印为0.00000000打印为0.00000000

满秩行打印为零,是保留八位小数后的表现,不是计算机采用无限精度。实际验收应使用容差比较,不应要求数组逐元素位级一致。原矩阵范数恰为四,因此每行相对残差可以直接用绝对残差除以四复核。

若预算只允许保留一个分量,本例会留下超过一半的相对残差;允许两个分量时降至约百分之六点八二。这个表能帮助选择重构秩,却没有留出集标签,所以不能宣称第三个分量使预测更准。未来接推荐数据时,缺失评分也不能随意当作真实零值,否则拟合对象已经换了。

九、常见问题与避坑

紧凑 SVD 是否只计算前几个奇异值?不是。紧凑输出省去多余正交方向,但本例仍得到全部三个奇异值。若只需要大矩阵的少量分量,需评估专门的截断或随机算法,并另行验证近似误差。

低秩一定节省存储吗?不一定。本例原矩阵十二个数;按秩二保存两个方向因子和奇异值,需要十六个数。低秩表征的存储收益应比较因子总元素数,而不是只看秩小于列数。

零矩阵的相对误差怎样写?先报告绝对误差为零,再声明相对口径不适用,或明确约定该特殊输入的返回值。不能把除零产生的无效值送进报告。

十、系统与库的差异

本次只在 Windows、Python 3.13.9 和 NumPy 2.3.5 执行。不同 BLAS 后端、硬件或版本可能改变浮点末位和运行时间;相同奇异值对应的向量还可能同时翻转符号。比较时关注重构、范数和方向子空间,不以向量每个元素的正负号判定算法错误。Linux 或 macOS 的环境目录和解释器路径需自行调整,本文没有给出跨系统性能结论。

十一、验证清单

  • 运行版本命令,确认实际解释器和 NumPy 版本。

  • 原矩阵应为四行三列,紧凑左因子四行三列,右因子三行三列。

  • 各秩残差不应因增加分量而上升;若上升,先检查三因子的切片是否一致。

  • 满秩用绝对容差验证重构,而不是依赖格式化后的零。

  • 一维样本应明确失败;失败时先检查输入形状。

  • 记录绝对误差、相对误差和尺度,不把三者混成一个准确率。

十二、面试题与追问

  1. SVD 为什么适合矩形矩阵?答:左右方向分别对应两个维数不同的空间,中间用非负奇异值连接。追问:四行三列矩阵紧凑输出各是什么形状?

  2. 截断重构应该切哪几部分?答:左因子前几列、奇异值前几项、右因子前几行一起切。追问:只截奇异值会怎样?

  3. 相对残差等于每个元素的误差率吗?答:不等于,它是整体范数的比值。追问:零矩阵为何需特殊处理?

  4. 紧凑输出等于部分求解吗?答:不等于,仍计算较小维度对应的全部奇异值。追问:什么时候考虑随机或截断求解器?

  5. 误差越低是否越有业务价值?答:不能直接推出,需独立业务目标和留出评测。追问:缺失评分当零会改变什么?

十三、小蓝伞的工程金句

“低秩保留的是组合方向,不是原始字段排行榜。”这句话对应本期三因子切片规则。另一个可操作判断是:“先问压缩了多少存储,再说压缩是否划算。”它对应小矩阵因子存储反而增长的例子。

十四、本篇技术清单与下一期

本期完成矩形矩阵分解、逐秩重构、范数误差和维度失败排查。下一期 AI-0216 导数与偏导数,将从“数据如何分解”转向“函数在当前位置怎样变化”,以解析求导和有限差分建立梯度的检验方法。沿系列继续读,可以把分解、求导和后续优化连接成同一条计算链。你的矩阵压缩预算更关注存储、重构误差,还是下游任务损失?先明确这一项再选秩。

官方资料

  • NumPy SVD:重构式、输出形状和奇异值顺序;本次核对本地安装包对应的官方函数说明。

  • NumPy 范数:Frobenius 范数参数;本次核对本地安装包函数说明和实际输出。

  • scikit-learn 分解与 PCA:中心化、缩放区别及随机分解的适用方向;2026-10-13 查阅。该资料不作为本例 NumPy 版本的接口证明。

适用边界

本文只验证手工小矩阵、实数双精度、二维接口及逐秩功能行为。代码按整数秩、有限非空矩阵使用;公共服务还需补参数类型、非有限值和资源上限。图像压缩、真实推荐预测、随机算法和大矩阵性能均未在本期实测。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询