假设一个预处理步骤在 AI 模型接收两个特征之前将它们混合。之后,你可能想为了调试、报告或另一个模型而恢复原始坐标。如何判断这个变换确实可逆?又如何在不做出脆弱的数值选择的情况下撤销它?
学完本课后,你将能够识别恒等行为,计算并验证一个小型矩阵的逆,区分逆矩阵和转置,识别奇异及近奇异情况,并解释为什么通常应直接求解线性系统,而不是显式构造逆矩阵。
**学习成果:**识别恒等行为并验证一个小型矩阵的逆。
第 20 课:矩阵-矩阵乘积复合变换与批处理说明了乘积如何复合线性映射。官方的 Mathematics for Machine Learning 配套网站在书籍 PDF 的第 2.2 节中介绍恒等、逆和转置运算,然后在第 2.3 节将它们连接到方程组。这里的记号沿用这一脉络,但数字、可视化、预处理场景、代码和问题都是原创的。
恒等意味着“保持坐标不变”
对于二维列向量,恒等矩阵是
I2=[1001].
乘以 I2 会让每个坐标保持不变。如果
x=[x1,x2]T,那么
I2x=[1001][x1x2]=[x1x2]=x.
对角线上的 1 保留每个坐标,非对角线上的 0 阻止一个坐标对另一个坐标产生贡献。恒等矩阵是数字 1 的矩阵版本:乘以它不会改变任何东西,但它为检查另一个矩阵是否已经被撤销提供了一个精确目标。
两边都很重要。矩阵乘积是有顺序的,因此一个有用的逆矩阵必须在左右两侧相乘时都还原出恒等矩阵,而不能只让某个选定的向量看起来正确。
逆矩阵撤销变换
设 A 是一个方阵。逆矩阵写作 A−1,它满足
AA−1=InandA−1A=In.
如果一个特征向量先变成 z=Ax,那么乘以 A−1 就能恢复输入:
A−1z=A−1(Ax)=(A−1A)x=Inx=x.
这是矩阵的消去规则。它并不是说每个矩阵都有逆。矩阵必须保留足够多的独立方向,逆才可能存在;当它不满足时,我们会看到究竟哪里出了问题。
可逆的二维特征变换先由 A 映射单位正方形,再由 A⁻¹ 将其还原。表格列出每个角点,因此图形并不是唯一的信息来源。这个平行四边形没有丢失信息:由于该示例的行列式不为零,四个角点与原始角点保持一一对应。
可视化使用的是
A=[2111],A−1=[1−1−12].
单位正方形在 A 作用下变成平行四边形,再在 A−1 作用下回到相同的角点。表格以静态、可读文本的形式记录每个角点的对应关系。由于这个 A 的行列式为 1 而不是 0,图形保持一一对应。
示例:求一个 2 × 2 矩阵的逆
对于
A=[acbd],
行列式为
det(A)=ad−bc.
当这个数不为零时,2 × 2 逆矩阵公式为
A−1=ad−bc1[d−c−ba].
这个公式内置了两项检查:交换对角线元素,给非对角线元素取相反数,再除以行列式。非零行列式使这次除法合法。
我们还可以通过变换一个特征向量来测试逆矩阵。令
x=[32].
正向映射得到
z=Ax=[2111][32]=[6+23+2]=[85].
逆矩阵将它还原:
A−1z=[1−1−12][85]=[8−5−8+10]=[32].
矩阵乘积检查比这个单向量检查更强。许多错误的矩阵恰好可以撤销某一个特定向量;只有恒等方程才能说明变换对空间中的每个向量都已被撤销。
逆矩阵不是转置
转置 AT 会交换行和列:
(AT)ij=Aji.
这是一种坐标轴重新定向。逆矩阵解决的是不同的要求 AA−1=I。在特殊情况下二者可以相等,但一般不能用一个运算替代另一个。
对于上面的示例矩阵,A 恰好是对称矩阵,所以 AT=A。但它的逆是
A−1=[1−1−12],
显然不等于 A。对称性本身不会使矩阵成为正交矩阵,也不会使其转置成为逆矩阵。
下面是一个非对称的反例:
B=[1021],BT=[1201],B−1=[10−21].
转置保留元素,却改变它们的方向。逆矩阵改变符号并组合坐标,使两个矩阵乘积变成恒等矩阵。只有当 QTQ=I 时——例如纯旋转或反射——才有 Q−1=QT。
AI 应用:撤销学习到的特征坐标变化
许多流水线处理的是中心化特征向量,而不是原始特征值。令 x∈R2 为原始的双特征向量,μ 为固定的均值向量。线性预处理步骤可以写成
z=A(x−μ).
矩阵 A 会混合并重新缩放中心化后的坐标。当后续模型在旋转过的或以其他方式重新表达的特征系统中工作得更好时,这可能很有用。如果 A 可逆且保留了同一个 μ,就可以使用
x=μ+A−1z.
逆矩阵并不是整个预处理流水线的魔法撤销按钮。它只能撤销这个特定的线性映射。如果流水线随后截断数值、丢弃特征、将数值四舍五入为整数,或应用非单射运算,那么丢失的信息不是任何矩阵逆都能重建的。
例如,取
μ=[104],x=[136],A=[2111].
先将特征向量中心化:
x−μ=[32].
变换后的坐标是 z=[8,5]T,与上面的示例相同。将它们还原得到
μ+A−1z=[104]+[32]=[136].
实用的调试习惯是同时记录坐标轴的含义、用于中心化的均值,以及矩阵的精确版本。来自较新预处理拟合的逆矩阵在数学上可能有效,但对于较旧批次来说仍可能是错误的逆矩阵。
奇异变换会丢失区别
考虑
S=[1224].
它的行列式为
det(S)=(1)(4)−(2)(2)=0.
第二行是第一行的两倍,因此 S 只有一个独立方向。它还会把不同的输入映射到同一个输出:
S[20]=[24]=S[01].
一旦这两个输入发生碰撞,仅观察输出就无法知道使用的是哪一个输入。逆矩阵必须把一个输出发送到两个不同的向量,但函数不可能做到这一点。对于奇异方阵,要求 numpy.linalg.inv 或 numpy.linalg.solve 运算时,NumPy 会将这种失败报告为 LinAlgError;参见逆矩阵文档和solve 文档。
奇异性不只是软件错误。它可能意味着特征映射压扁了某个方向、两列彼此冗余,或模型表示没有包含重建所需的足够信息。伪逆或最小二乘估计对于另一个问题仍可能有用,但它不是 S 的精确双侧逆。
近奇异是数值警告,而不是成功
现在将一个元素改变一个非常小的量:
N=[1111+10−8].
它的行列式约为 10−8,因此在技术上可逆。但它的两行几乎平行。很小的测量误差或舍入变化都可能导致恢复向量发生很大变化。条件数可以概括这种敏感性;在通常的 2-范数下,接近 4×108 的值意味着求解过程可能消耗输入精度中的许多位。NumPy 将这个诊断提供为 numpy.linalg.cond。
这个区分很重要:
| 矩阵状态 | 行列式测试 | 实际解释 |
|---|
| 非奇异且条件良好 | 非零,且相对于尺度不太小 | 对可用的数据精度而言,逆矩阵或求解可能可靠。 |
| 奇异 | 精确算术中恰好为零 | 不同输入可能已经塌缩为一个输出;不存在普通逆矩阵。 |
| 近奇异 | 非零,但相对于尺度较小 | 纸面上存在逆矩阵,但输入噪声可能被强烈放大。 |
行列式并不是通用的无尺度安全阈值。将矩阵乘以一个大标量也会改变行列式,因此还要检查条件数、奇异值、残差和应用的尺度。浮点行列式非零,只能说明这个表示具有可逆性的证据,并不能保证重建值得信赖。
为什么 solve 优于构造显式逆矩阵
方程
Ax=b
在 A 可逆时的数学解是 x=A−1b。但在代码中,如果你只需要 x,就没有必要先构造完整的 A−1。numpy.linalg.solve直接接收 A 和 b 并计算方程组的解;numpy.linalg.inv则会构造逆矩阵本身,并警告条件不良的结果可能不准确。
因此,推荐的实现模式是:
import numpy as np
A = np.array([[2.0, 1.0],
[1.0, 1.0]])
b = np.array([2.0, 1.0])
x_from_solve = np.linalg.solve(A, b)
x_from_inverse = np.linalg.inv(A) @ b
np.testing.assert_allclose(x_from_solve, [1.0, 0.0])
np.testing.assert_allclose(x_from_inverse, x_from_solve)
np.testing.assert_allclose(A @ x_from_solve, b)
对于这个小型且条件良好的示例,两条路径的结果一致。重要的工程差异在于,solve 会计算所需的解,而不会实体化一个你可能永远不会使用的矩阵。它还让求解系统的算法保持明确,使代码表达真正的任务:求解 Ax=b。
如果多个右端项共享同一个 A,就将它们作为矩阵 B 的列传入,一次求解 AX=B。如果 A 是奇异的,solve 就不是求精确解的正确工具;只有当最小二乘等方法的不同目标符合应用时,才选择它。始终检查残差:
r=Ax−b.
以问题单位表示的较小残差,是计算向量确实求解了给定系统的证据。但它本身不能证明系统条件良好,也不能证明矩阵代表了正确的预处理步骤。
下一课将通过行运算明确展示求解步骤。现在,恒等矩阵是目标,逆矩阵是可逆映射,转置是轴交换,而条件性告诉我们一个数学上合法的撤销在数值上是否合理。
检查你的理解
问题 1
I₂ 对向量 [4, −3]ᵀ 做什么?为什么?
显示分步解答
第 1 步:写出恒等矩阵。
I2=[1001].第 2 步:逐行乘以列。
I2[4−3]=[1⋅4+0⋅(−3)0⋅4+1⋅(−3)]=[4−3].**第 3 步:解释。**对角线上的 1 保留每个坐标,0 阻止坐标之间混合,因此恒等矩阵保持向量不变。
问题 2
使用 2 × 2 公式,求 A = [[1, 2], [3, 7]] 的逆。
显示分步解答
**第 1 步:确定各元素。**这里 a=1、b=2、c=3、d=7。
第 2 步:计算行列式。
ad−bc=(1)(7)−(2)(3)=7−6=1.行列式不为零,因此逆矩阵存在。
第 3 步:交换并取相反数。
A−1=11[7−3−21]=[7−3−21].在这个特定示例中,除以行列式不会改变元素,因为行列式等于 1。
问题 3
通过计算 A A⁻¹,验证问题 2 中的逆矩阵。
显示分步解答
使用
A=[1327],A−1=[7−3−21].第 1 步:计算每个元素。
AA−1=[1⋅7+2⋅(−3)3⋅7+7⋅(−3)1⋅(−2)+2⋅13⋅(−2)+7⋅1]=[1001].**第 2 步:与目标比较。**结果是 I2,所以所提出的矩阵通过了左乘积检查。因为这是一个方阵的逆,且公式给出了匹配的双侧逆,所以它也会在另一侧撤销矩阵;计算 A−1A 是一项有用的额外代码检查。
问题 4
对于 B = [[1, 2], [0, 1]],Bᵀ 是有效的逆矩阵吗?写出足够的乘法来判断。
显示分步解答
第 1 步:写出转置。
BT=[1201].第 2 步:用 B 乘以它的转置。
BBT=[1021][1201]=[5221].**第 3 步:与恒等矩阵比较。**这不是 [1001],所以 BT 不是逆矩阵。实际上,B−1=[10−21];转置和逆矩阵回答的是不同的问题。
问题 5
某个预处理步骤使用 z = A(x − μ),其中 μ = [10, 4]ᵀ、A = [[2, 1], [1, 1]],且 z = [8, 5]ᵀ。恢复 x。
显示分步解答
第 1 步:使用预处理方程的逆形式。
x=μ+A−1z.第 2 步:使用已经验证过的逆矩阵。
A−1z=[1−1−12][85]=[32].第 3 步:恢复均值。
x=[104]+[32]=[136].忘记 μ 只能恢复中心化坐标,而不是原始特征值。
问题 6
为什么 S = [[1, 2], [2, 4]] 没有普通逆矩阵?请给出几何或基于信息的解释。
显示分步解答
第 1 步:检查行列式。
det(S)=(1)(4)−(2)(2)=0.行列式为零意味着行和列不包含两个独立方向。
第 2 步:展示信息损失。
S[20]=[24]=S[01].两个不同的输入产生同一个输出。一个函数如果只接收到这个输出,就无法决定应该返回哪个输入,因此不存在双侧逆矩阵。
问题 7
一个矩阵的行列式不为零,但条件数约为 4 × 10⁸。可以断言求逆没有风险吗?请解释。
显示分步解答
**第 1 步:区分存在性与敏感性。**非零行列式说明矩阵在精确算术中可逆,但它没有说明逆矩阵在舍入或带噪输入下稳定。
**第 2 步:解释条件数。**接近 4×108 的条件数表明矩阵近似奇异:输入中的微小相对变化可能在恢复的解中被放大许多个数量级。
**第 3 步:选择结论。**不要说求逆没有风险。检查数据精度、残差、奇异值或条件数,以及应用的容差。数学上有效的逆矩阵仍可能导致糟糕的数值重建。
问题 8
当只需要 x 时,将 x = A⁻¹b 改写为 NumPy 代码,并说出一项之后应执行的验证。
显示分步解答
**第 1 步:表达直接任务。**方程是 Ax=b,因此应让 NumPy 求解该系统:
x = np.linalg.solve(A, b)
**第 2 步:解释选择。**当不需要逆矩阵本身时,这避免构造 np.linalg.inv(A),也直接表达了预期的运算。
**第 3 步:验证结果。**计算残差,并将它与右端项比较:
np.testing.assert_allclose(A @ x, b)
这会检查返回的向量是否在容差范围内求解了给定系统。如果输入可能近似奇异,也要检查条件性。