1. 当误差遇上正态分布:最小二乘法的前世今生

我第一次接触最小二乘法是在大学物理实验课上。当时为了拟合弹簧的劲度系数,教授让我们在坐标纸上描点画线。有个同学突然举手问:"为什么非要让所有点到直线的垂直距离平方和最小?取绝对值或者四次方不行吗?"教授推了推眼镜说:"这是个价值连城的问题。"现在想来,这个问题的答案藏在200多年前高斯写下的那个钟形曲线里。

勒让德在1805年提出最小二乘准则时,确实没有严格证明为什么要用平方误差。这就像厨师知道加盐能让菜变好吃,但说不清氯化钠分子如何刺激味蕾。直到1809年,高斯在《天体运动论》中给出了关键解释:当观测误差服从正态分布时,使平方误差最小的参数估计,恰好就是最可能产生当前观测数据的真实参数。这就把做菜的直觉变成了化学反应方程式。

举个生活中的例子:假设我们要估计某品牌空调的日均耗电量。测量10次得到的数据波动,就像射击运动员在靶子上留下的弹孔分布——大部分集中在中心区域,少数偏离较远。这种"中间密、两边疏"的分布形态,正是高斯分布最擅于描述的现象。当我们用平方误差最小化来拟合时,本质上是在寻找最可能产生这个弹孔分布的中心点位置。

2. 极大似然估计:概率视角下的必然选择

2.1 从射击游戏理解概率模型

想象你在游乐场玩射击游戏,每次瞄准靶心击发时,由于手抖、风速等因素,弹着点会随机偏离。假设偏差在水平垂直两个方向都服从正态分布,那么靶纸上的弹孔分布就会形成典型的二维高斯分布。现在给你一张满是弹孔的靶纸,如何反推射击者的真实瞄准点?

这正是极大似然估计要解决的问题。在概率论中,似然函数表示在给定参数下观察到当前数据的概率。对于正态分布噪声模型,单个数据点$y_i$的似然函数是:

$$ p(y_i|x_i;\theta) = \frac{1}{\sqrt{2\pi}\sigma}\exp\left(-\frac{(y_i-f_\theta(x_i))^2}{2\sigma^2}\right) $$

这个公式就像个概率显微镜——$f_\theta(x_i)$是理论瞄准点,$\sigma$决定弹着点的分散程度。当观测值$y_i$距离理论值越远,其出现的概率密度就呈指数级衰减。

2.2 连乘变求和的对数魔法

由于各次观测相互独立,整个数据集的联合概率就是各点概率的乘积。但直接处理连乘运算会遇到数值下溢问题,就像计算(0.1×0.1×...×0.1)很快就会超出计算机的表示范围。这时取对数就显示出三大优势:

  1. 将连乘转为求和,避免数值溢出
  2. 保持函数的单调性,不影响极值位置
  3. 指数项转化为多项式,便于求导

经过对数变换后,我们得到的目标函数是:

$$ J(\theta) = -\frac{1}{2\sigma^2}\sum_{i=1}^m (y_i-f_\theta(x_i))^2 - m\ln(\sigma\sqrt{2\pi}) $$

这个式子揭示了一个重要事实:最大化似然函数等价于最小化平方误差和。因为公式中只有第一项与模型参数$\theta$相关,而第二项可以看作常数偏置。

3. 最小二乘法的现代演绎:从线性回归到深度学习

3.1 线性回归的闭式解

在简单线性回归中,假设模型为$f_\theta(x) = wx + b$。将平方误差函数对参数$w$和$b$求导并令导数为零,可以得到著名的正规方程:

$$ \begin{bmatrix} w \ b \end{bmatrix} = (X^TX)^{-1}X^T y $$

其中$X$是设计矩阵,第一列为输入特征,第二列为全1向量。这个解析解就像用万能钥匙开的锁——干净利落但缺乏灵活性。我在第一次实现时曾犯过典型错误:当特征之间存在多重共线性时,$X^TX$矩阵可能不可逆。这时就需要引入正则化或使用伪逆。

3.2 梯度下降:神经网络的动力源

对于复杂的深度神经网络,闭式解就像试图用解析方法求解湍流方程——理论上可行但实际不可操作。这时梯度下降法就派上用场了。以平方误差损失为例,参数的更新规则为:

# 小批量梯度下降示例
def update_params(X_batch, y_batch, w, lr=0.01):
    error = y_batch - X_batch.dot(w)
    gradient = -2 * X_batch.T.dot(error) / len(X_batch)
    return w - lr * gradient

这个简单的迭代过程蕴含着深刻的哲学:每个微小的参数调整都在降低模型预测与观测数据之间的不协调性。就像雕塑家每次凿去不符合预期的部分,最终呈现出隐藏在大理石中的形态。

4. 超越最小二乘:当高斯假设不成立时

4.1 重尾分布与鲁棒回归

现实中的数据污染就像咖啡里的盐——少量就能毁掉整杯饮品。当误差分布出现重尾(heavy tail)时,最小二乘估计会变得异常敏感。这时可以考虑以下替代方案:

  • Huber损失:在原点附近使用平方误差,远处转为线性

    def huber_loss(e, delta=1.0):
        return np.where(np.abs(e) < delta, 0.5*e**2, delta*(np.abs(e)-0.5*delta))
    
  • Tukey双权函数:对异常值给予渐进零权重

我在分析金融时间序列时曾对比过不同损失函数。当数据中存在"黑天鹅"事件时,传统最小二乘的预测区间会荒谬地扩大,而鲁棒回归则保持了稳定。

4.2 异方差性的处理方案

另一个常见问题是误差方差随输入变化(异方差性)。比如在预测房价时,高端住宅的价格波动通常更大。这时可以考虑:

  1. 加权最小二乘:给不同样本分配不同权重
  2. 对数变换:压缩数据的动态范围
  3. 广义线性模型:建立方差与均值的函数关系

记得有次处理传感器数据,发现误差幅度与测量值成正比。简单的取对数操作就让模型的$R^2$从0.6提升到了0.85,这比复杂模型调参来得高效得多。

在结束前分享一个实用技巧:当实现最小二乘算法时,记得对输入特征做标准化处理。这不仅加速收敛,还能避免数值不稳定。我曾因为忽略这点,在求解正规方程时得到荒谬的参数值——某些系数达到$10^{15}$量级,这就是计算机浮点精度导致的灾难。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐