投影与最小二乘
你想用「面积」预测房价,手里有 200 套成交记录。两个未知数(单价和底价),200 个方程——除非所有房子完美排成一条直线(不可能),这个方程组无解。但没有人因此下班:我们要的从来不是完美穿过每个点的直线,而是最不离谱的那条。「无解时求最像的解」,这门手艺叫最小二乘,它的几何本体是一次投影。这一章是卷三的收官,也是全书第一次完整演示「机器学习」的最小原型:定义误差、最小化误差、解出参数——闭式解,一步到位。
无解是常态,不是事故
把房价问题写成矩阵。每套房一个方程「单价 × 面积 + 底价 = 售价」,拼起来就是 Ax = b:A 有 200 行(每行一套房:面积, 1)、2 列;x 是待求的 (单价, 底价);b 是 200 个真实售价。注意那根全 1 的列——它就是第 03 章预告的「偏置项」:没有它,直线被迫过原点,零面积的房子必须零元,拟合从第一步就输了。这种「方程多、未知数少」的系统叫超定(overdetermined)。用第 09 章的列图像秒懂它的绝望:A 的两根列向量住在 ℝ²⁰⁰ 里,张成的列空间只是一张 2 维薄片;b 是 ℝ²⁰⁰ 里的任意一点,落在这张薄片上的概率是零。b 够不着,Ax = b 无解——这不是数据脏,是维度的宿命。
既然够不着,退而求其次:在列空间这张薄片上,找离 b 最近的点 p̂,解「够得着的替代问题」Ax̂ = p̂。「最近」用什么尺子?L2 范数(第 05 章),即最小化残差向量 r = b − Ax̂ 的长度平方——「最小二乘」(least squares)四个字,拆开就是「让平方和最小」。
垂直,是「最近」的签名
值得先欣赏一下这步「换问题」的手腕:原问题(精确解)无解,我们没有降低标准硬凑,而是换了一个有唯一解、且答案有明确「最优」含义的新问题。这种「把不可解问题松弛成最优化问题」的操作,是应用数学的万能钥匙——机器学习整个学科都住在这把钥匙开的门后面。
最近点在哪?几何给出不需要微积分的答案:从 b 向薄片作垂线,垂足就是 p̂——任何斜着的连线都比垂线长(勾股定理)。于是「最优」有了一个可以写成方程的签名:残差 r 必须垂直于整个列空间,也就是垂直于 A 的每一根列:
第一步值得咀嚼:「r 垂直于 A 的每一列」= 「每一列与 r 的点积为零」= Aᵀr = 0(转置矩阵乘向量,恰好是批量点积——第 07 章欠的「转置的几何意义」在此兑现:Aᵀ 是拿 A 的列当探测器,逐一测量输入)。整理即得正规方程:一个 2×2 的小系统,solve 一下,200 个方程的「最优妥协」就出来了。没有迭代,没有学习率,没有炼丹——线性模型 + 平方误差的组合,最优解是一步到位的几何事实。
是时候亲手拖一拖了:
实验清单:① 随便拖几个点,观察紫线永远「瞬间」跟上——它不是逐步逼近的,是解方程解出来的;② 盯住灰色虚线(残差):最优直线的残差有正有负、上下抵账,这是「垂直」在数据视角下的样子;③ 杠杆实验:把最右边的点拖到很高,看整条线被它撬起来多少,再把中间的点拖到同样高度对比——离群点越靠边,杠杆越长,危害越大(第 05 章 MSE「讨好离群点」的现场版);④ 点「加点噪声」几次,看直线在噪声下的抖动幅度,体会「估计的方差」——同一套真实规律,不同的噪声实现,给出略不同的参数,这正是统计学里「估计量有分布」的手感;⑤ 把所有点拖成近似两团(左低右高),再拖出一个「桥中间」的点,观察它对斜率几乎没有话语权:杠杆取决于横向位置,不取决于纵向偏离。
一遍带数字的完整流程
用三个点 (0, 1)、(1, 2)、(2, 2) 拟合 y = mx + c,把抽象符号全部落地:
import numpy as np A = np.array([[0.0, 1.0], # 每行一个点:[x, 1] [1.0, 1.0], [2.0, 1.0]]) b = np.array([1.0, 2.0, 2.0]) # 正规方程(教学演示用):AᵀA x = Aᵀb AtA = A.T @ A # [[5, 3], [3, 3]] Atb = A.T @ b # [6, 5] x_hat = np.linalg.solve(AtA, Atb) # [0.5, 1.1667] → y = 0.5x + 7/6 # 生产写法:一行,数值更稳 x_best, res, rank, sv = np.linalg.lstsq(A, b, rcond=None) # 验证「垂直」签名:残差与每一列点积 ≈ 0 r = b - A @ x_hat A.T @ r # [~0, ~0] ✓ # 岭回归:对角线加 λ,共线也稳 lam = 0.1 x_ridge = np.linalg.solve(AtA + lam * np.eye(2), Atb)
三个点不在一条线上(前两点斜率 1,后两点斜率 0),方程组无解;最小二乘拍板 y = 0.5x + 7/6,三个残差 (−1/6, +1/3, −1/6)——上下抵账、与两列垂直,全部对得上。lstsq 顺手还返回了 rank 和奇异值 sv,免费送你一份第 12 章的体检报告:rank < 列数就是共线警报。
投影矩阵:把「拍扁」写成矩阵
还记得第 04 章「投影到一条线」的公式 proj = (v·w/|w|²)w 吗?本章是它的多维完全体:一条线换成一张列空间薄片,点积换成 Aᵀ,除以 |w|² 换成乘 (AᵀA)⁻¹——形状变复杂,骨架一模一样。从正规方程解出 x̂ = (AᵀA)⁻¹Aᵀb,代回去得到投影点 p̂ = A(AᵀA)⁻¹Aᵀb。盯住中间那坨:
这就是第 10 章动物园里那只「幂等兽」的完全体:P² = P(影子的影子还是影子,代入化简一行可验),对称,特征值非 0 即 1。它把整个 ℝ²⁰⁰ 拍扁到 2 维薄片上,拍扁方向正是「残差方向」。而 x̂ 前面那坨 (AᵀA)⁻¹Aᵀ 也有名字:A 的伪逆(pseudo-inverse,记 A⁺)——第 09 章预告的「非方阵最像逆的东西」:A 不可逆(不方),但 A⁺b 给出「让 ‖Ax − b‖ 最小」的答案,是「逆」这个概念在无解世界里的合法继承人。np.linalg.pinv 就是它,底层用 SVD 造(第 17 章会看到造法美得过分)。
教科书推导用正规方程,生产代码别用它硬算。AᵀA 会把条件数平方(第 09 章的病态剪刀口,平方后加倍锋利):特征略有共线,AᵀA 就在数值上奇异,解出来的系数天马行空——第 11 章「双身高惨案」的完整病理链:列几乎相关 → AᵀA 病态 → 系数爆炸。数值正道是 np.linalg.lstsq(QR 或 SVD 路线,不显式构造 AᵀA)。另一个经典误会:最小二乘量的是竖直方向的残差(y 的误差),不是点到直线的垂直距离——「垂直」发生在 200 维的列空间里,不在你看到的二维散点图里;真要最小化几何垂距是另一个问题(全最小二乘),答案要用 SVD。
为什么偏偏是「平方」
「最小化残差的平方和」——为什么不是绝对值和(L1)、不是四次方和?第 05 章给过工程答案(各有性格),这里补上两条更深的理由。其一,几何:只有 L2 的「最近」才等价于「垂直投影」,才有正规方程这个闭式解;换 L1,解要靠线性规划迭代,几何图像也不再是干净的垂线。其二,概率:如果假设测量误差服从高斯分布(大量独立小扰动叠加的极限,自然界的默认噪声),那么「最大化数据的出现概率」(最大似然)在数学上恰好等价于「最小化残差平方和」。平方不是拍脑袋,是高斯噪声假设的影子——数据要真是重尾噪声(异常值频出),高斯假设破产,L1/Huber 才是对症的药。这条「度量背后站着一个噪声假设」的原理,值得放进你的建模世界观。
顺带的历史注脚:最小二乘由勒让德 1805 年发表、高斯声称 1795 年就在用(为了预测谷神星轨道,他赢了),是数学史上著名的优先权公案。两百二十年过去,它仍是每天被执行最多次的统计算法——你手机里每一次传感器融合、每一条回归基线,都是这场公案的遗产。
另一头的麻烦:方程太少
超定的对面是欠定(underdetermined):方程比未知数少,m < n,解有无穷多(第 09 章「无穷多解」的常态版)。这时的选择题不是「哪个最近」,而是「这么多解,挑哪个」。最小二乘家族的默认答案:挑范数最小的那个——所有合法解里离原点最近的,「能用小数字解释就别用大数字」的奥卡姆剃刀。美妙的是,伪逆 A⁺ 一视同仁地处理两头:超定时给最小残差解,欠定时给最小范数解,一个公式包办「无解」与「解太多」两种尴尬。大模型时代欠定是常态——参数(几十亿)远多于训练约束能钉死的自由度,「无穷多组参数都能拟合训练集,优化器实际挑了哪一组、为什么这组泛化不错」正是深度学习理论的核心悬案之一(隐式正则化)。你不需要答案,但你现在拥有提问的语言。
这就是机器学习的最小原型
把这一章的流程排成清单:选模型形状(直线)→ 定误差度量(残差平方和)→ 最小化 → 得参数。这四步就是一切监督学习的骨架,后面所有花样都是替换部件:模型形状换成深度网络(卷五),误差换成交叉熵,最小化从「解方程」换成「梯度下降」(因为非线性模型没有闭式解,第 09 章「直接法失效退迭代法」的祖训)。特征也不必只是原始输入——把 A 的列换成 x、x²、sin(x)、别的模型的输出,「线性」模型立刻能拟合曲线:线性指的是对参数线性,不是对数据线性,这个区分让最小二乘的适用面比看上去宽一个数量级(多项式回归、样条、核方法的前半句,都是它)。线性回归是唯一能「一步解出全局最优」的特权阶级,所以它永远是新算法的第一块试金石、新数据的第一条基线——先跑个线性回归看看,是数据科学的「先 ping 一下」。
四个直连:① 线性探针(linear probe):冻住大模型,取某层激活当特征,只训一个线性层判断「这层是否已包含某信息」——那个线性层的训练,常常就是一次岭回归/最小二乘,本章公式直接上岗;② 岭回归 = 正规方程加保险丝:(AᵀA + λI)x̂ = Aᵀb,往对角线加 λ 强行恢复可逆,同时正是 L2 正则(第 05 章)的闭式形态——两条线索在此合流;③ 模型蒸馏与对齐的「回归头」、推荐系统的交替最小二乘(ALS,固定用户矩阵解物品矩阵、再反过来,每一步都是本章)——第 12 章的 Netflix 分解,训练算法就叫这个名字;④ 神经网络最后一层若是线性 + MSE,梯度下降收敛的终点恰好就是最小二乘解——深度学习的终点站里,常常坐着一位十九世纪的高斯。
还有一条容易被忽略的心理收益:最小二乘给了「拟合」一个可讲道理的唯一答案。两个人各画一条「看起来都行」的趋势线,争不出对错;定了度量,答案唯一,分歧就从审美问题变成假设问题(你假设高斯噪声?我假设重尾?)——可以检验,可以让步,可以复现。把争论从「像不像」搬到「假设对不对」,是定量学科的成人礼,也是你以后评审模型方案时该守的规矩。
你每次滑动列表松手,VelocityTracker 都在做一次小型最小二乘:它攒下手指最近若干个 (时间, 位置) 采样点,拟合一条低阶多项式曲线,读出松手瞬间的速度,交给 fling 动画。采样点有抖动(触摸屏噪声),单点差分算速度会疯,拟合曲线求导才稳——这正是「用最小二乘对抗噪声」的教科书应用。另一个藏得更深的:磁力计校准(那个画 8 字的仪式)本质是把一堆读数拟合成椭球、解出偏移矩阵,同样是一族最小二乘问题。
看残差,别只看拟合优度
老练的建模者拿到拟合结果,第一眼看的不是「误差多小」,而是残差长什么样。残差是模型「解释不了的部分」,它的形态是一份免费的诊断报告:
- 残差像白噪声(无规律、正负均匀):模型形状选对了,剩下的是真噪声,收工。
- 残差带弧形趋势:数据其实是弯的,直线模型「系统性地」在两端低估、中间高估——该加二次项或换模型,而不是加数据。
- 残差喇叭口(越往右散得越开):误差的方差不恒定,平方损失的「民主投票」被大方差区绑架,考虑加权最小二乘。
- 个别残差鹤立鸡群:离群点。先查数据管道,再考虑 Huber。
这个习惯直通深度学习:训练损失降不动时,看「哪类样本的损失高」(残差分析的现代版)比盲目调参有效得多;论文里的 error analysis 章节,精神完全同源。误差的大小决定模型能不能用,误差的形态告诉你下一步改哪里。
正交基的特权:投影白送
最后收一条前面埋的线。如果 A 的列恰好是标准正交的(第 11 章 Gram–Schmidt 的产物),那么 AᵀA = I,正规方程直接塌缩成 x̂ = Aᵀb——投影系数 = 挨个做点积,连方程都不用解。这就是「标准正交基特权清单」里最实用的一条:傅里叶系数为什么是「信号点积正弦波」?PCA 降维为什么是「数据点积主成分」?因为它们的基都正交,投影退化成点积。一条公式解释两大工具的手感,这笔投资第 17、18 章连本带利返还。
① 三个点 (0,1)、(1,2)、(2,2) 拟合直线 y = mx + c:写出 A、b,解正规方程(2×2,手算friendly),验证残差与 A 的两列都垂直;
② Demo 里把七个点拖成完美一条直线,残差会怎样?此时 b 和列空间什么关系?
③ 为什么岭回归的 AᵀA + λI 一定可逆?(提示:第 10 章正定 + 对角加载);
④ lstsq 和「先算 AᵀA 再 solve」结果几乎一样,为什么前者仍是正道?
⑤ 线性探针训出来 92% 准确率,能证明模型「懂」这个概念吗?——想想线性可分与「懂」之间差了什么(开放题,第 20 章再会)。
小结:卷三收官
超定系统无解是维度的宿命;最小二乘在列空间上找 b 的垂直投影,「残差 ⊥ 每一列」浓缩成正规方程 AᵀAx̂ = Aᵀb;投影矩阵幂等对称,伪逆是逆在无解世界的继承人;数值上走 QR/SVD,别把条件数平方;正交列让投影退化成点积。更重要的是格局:定形状、定度量、最小化、得参数——机器学习的骨架在这一章第一次完整合龙。残差的形态比大小更有信息量,平方损失背后站着高斯噪声假设,欠定问题的解由「最小范数」拍板——三条都是能直接带进工作的判断力。卷三到此收官:维度(11)、秩(12)、换基(13)、投影(14),空间的语法已经齐了。卷四开始拆矩阵的内脏——第一刀切向那个变换自己都藏不住的秘密:有些方向,它只能缩放,不能扭转。