上一节:人工智能概述和特征提取?做人工智能的第一步中提到:所有复杂的原始数据(图像、文本、用户)都必须通过强业务绑定的特征工程(向量化)过程,转换为统一的数值向量,才能输入给机器学习模型进行学习和预测。即数据 \(\rightarrow\) 向量化 \(\rightarrow\) 模型。
而学习机器学习,就是学习各种模型,即学习各种传统AI算法。
这节主要学习线性回归算法。
首先需要明确线性回归算法的需求:


如图,用于训练模型的数据集(train_data)共有 499 个样本。
线性回归模型的核心需求是利用所有 多个输入-输出数据对 \((x_i, y_i)\),找到一个最优的线性函数来近似输入 \(x\) 和输出 \(y\) 之间的关系。
模型表达式:
\[\hat{y} = w \cdot x + b\]其中,\(\hat{y}\) 是预测值,\(w\) 是权重,\(b\) 是偏置。
学习目标: 模型的首要需求是确定(估计)最优的参数 \(w\) 和 \(b\)。
如何找到最优?首先要量化。其次要定义误差。
线性回归常见的就是用MSE进行误差的计算,公式是
\[\text{mse} = \frac{1}{n} \sum_{i=1}^{n} (\hat{y}_i - y_i)^2\]其中\(\hat{y}_i = w x_i + b\)
MSE 的值越小,说明模型的预测 \(\hat{y}_i\) 越接近真实值 \(y_i\),模型的性能越好。
测试集的误差(MSE)一定大于训练集的误差吗?不是。
虽然测试集是随机抽样的,但它可能偶然性地包含了比训练集更接近拟合直线的数据点。但是,在真实的环境中,测试集的mse一般大于训练集的mse
\(\text{MSE}_{\text{Test}} < \text{MSE}_{\text{Train}}\) 是一种异常现象,虽然可能发生,但它通常提示您:您的数据划分可能存在偶然性,或者您的实验设计中可能存在数据泄露问题。
要使得测试集的MSE小,可以采用:
- 训练集变大
- 训练集数据符合真实的环境
推广能力(泛化能力):能在测试集上表现良好的能力
面试题1:测试集的mse和训练集的mse谁大谁小
首先,理论上,测试集的均方误差 (\(\text{MSE}_{\text{Test}}\)) 与训练集的均方误差 (\(\text{MSE}_{\text{Train}}\)) 没有绝对的、统计学的必然大小关系。
- \(\text{MSE}_{\text{Test}} > \text{MSE}_{\text{Train}}\) (常见且合理): 这是最常见的情况,表明模型在未见过的数据上性能略有下降,反映了模型的泛化能力。如果差距过大,则表明模型过拟合。
- \(\text{MSE}_{\text{Test}} < \text{MSE}_{\text{Train}}\) (可能但罕见): 这是可能的,通常是由于数据随机性或统计巧合。测试集可能恰好抽样到了比训练集更接近真实关系的数据点,使得模型在其上的表现更好。
其次,在实际的机器学习工程项目中,我们通常观察到的结果是:测试集的 MSE 大于训练集的 MSE。
- 模型的训练过程(优化算法)被设计为最小化训练集上的误差。模型所有参数的调整都以这个目标为依归。
- 工程抽样: 虽然理论上存在 \(\text{MSE}_{\text{Test}} < \text{MSE}_{\text{Train}}\) 的可能性,但在实际的、拥有大量数据和合理划分的工程实践中,很难稳定地采样到这种“测试集更容易”的情况(概率很低)。因此,经验上,\(\text{MSE}_{\text{Test}} \ge \text{MSE}_{\text{Train}}\) 是常态。
当观察到 \(\text{MSE}_{\text{Test}}\) 显著大于 \(\text{MSE}_{\text{Train}}\)(即模型过拟合)时,主要的解决思路是提高模型的泛化能力。
- 增大训练集,增加训练集的多样性: 引入更多、更具有代表性的数据,让模型能够学习到更普遍的规律,而不是只记住现有训练集的噪声和细节。
- 其他常用方法(补充):
- 正则化: 在损失函数中加入惩罚项(如 L2正则化Ridge/L1正则化Lasso),限制模型参数的复杂性。
- 特征选择/降维: 减少输入特征的数量,降低模型复杂度。
- 提前停止 (Early Stopping): 在验证集误差开始上升时,就停止训练。
面试题2:感性分析为什么MSE是平方项而不是绝对值
模型“注意力”转移
下面详细解释为什么在回归问题中,均方误差(MSE,即误差的平方)比绝对值误差(MAE,即误差的绝对值)更常被使用,特别是从模型“注意力”转移的角度进行解释。
一堆数据点,有些难预测,有些容易预测
\[(y - \hat{y})^2\]把容易预测的MSE降低到一定程度后,再在容易点上优化,收益就变小了。那注意力就会转移到难预测的焦点上
如果用绝对值误差,收益永远不变,注意力就总在容易预测的焦点上了
核心原因在于:平方惩罚(MSE)会随着误差的增大而加速增大,这使得模型“更关注”那些预测得很差的“难点”。
比较误差的平方(MSE)和误差的绝对值(MAE)。
| 真实误差 | |y - ŷ| | 平方误差 (MSE) | 绝对值误差 (MAE) |
|---|---|---|---|
| 小误差 (例如 0.1) | 0.1 | 0.1² = 0.01 | |0.1| = 0.1 |
| 大误差 (例如 10) | 10 | 10² = 100 | |10| = 10 |
模型训练初期,模型的预测普遍较差,大误差很多。此时,模型计算出的总 \(\text{MSE}\) 会非常大,因为大误差被平方放大了( 10变成了100)。
模型优化阶段,模型首先会快速修正那些大误差的点(“难预测的点”),因为修正它们可以使MSE快速、大幅度地下降,收益最大。
所以模型训练后期,难预测的点被修正得差不多了。
如果使用绝对值误差(MAE),惩罚与误差是线性关系。
- 惩罚一致性: 无论是将一个大误差10修正到9,还是将一个小误差0.1修正到0,对总MSE带来的下降值是差不多的(都是 1或 0.1)。
- 模型会发现,优化那些容易预测的点(通常意味着它们离拟合线已经很近,优化成本低)和优化那些难预测的点(优化成本高)的收益是相对恒定且均衡的。
- 模型的“注意力”可能总是在那些容易优化的点上打转,因为它可以在这些点上以较低的代价获得与修正难点一样的收益。这可能导致模型不愿冒险去修正那些与现有拟合线偏差很大的难预测的点,使它们长期保持较大的残差。
平方误差(MSE)的关键作用在于其非线性惩罚机制:它对大误差的惩罚不成比例地加大,强制模型优先关注并修正最严重的预测错误(难预测的点),从而确保模型的拟合结果能照顾到所有数据点,避免少数几个异常值被模型完全忽视。
下面是代码,可以论证上面的结论:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import random
def get_data(w, num):
x = [random.uniform(0, 5) for i in range(num)]
y = [w * s for s in x]
return list(zip(x, y))
def train_step_pow(data, w, rate=0.03):
g = sum((w * x - y) * x for x, y in data) / len(data)
w = w - rate * g
return w
def train_step_abs(data, w, rate=0.03):
g = sum(x if (w * x - y) > 0 else -x for x, y in data) / len(data)
w = w - rate * g
return w
def cal_data_error(data, w):
error = [(w * x - y) ** 2 for x, y in data]
return error
# First parameter is w, second is the number of data points
data = get_data(10, 10) + get_data(6, 2)
w1 = w2 = 7
for i in range(5000):
w1 = train_step_pow(data, w1) # MSE training
w2 = train_step_abs(data, w2) # MAE training
if i % 50 == 0:
print(f"{w1:.3f},{w2:.3f}")
代码中,有2类点:
- 主体数据 (10 个样本): 由
get_data(10, 10)生成,它们遵循模型 \(y = 10x\)。目标最优解 \(w^*\) 是 10。 - 异常值/离群点 (2 个样本): 由
get_data(6, 2)生成,它们遵循模型 \(y = 6x\)。这些样本是相对于主体数据的强离群点。
模型必须在主体数据 \(w=10\) 和异常值 \(w=6\) 之间做出权衡。由于主体数据占 \(10/12 \approx 83.3\%\),最优的妥协解 \(w^*\)应该非常接近10,但会略微偏向6。
train_step_pow (对应 MSE 损失,是平方项)
train_step_abs (对应 MAE 损失,是绝对值项)
运行这段代码的结果如下:(每次运行会有区别,但是可以看到大体趋势)

发现,\(w1\)(MSE 训练结果)通常会收敛到9点多,明显小于10。
\(w2\)(MAE 训练结果)通常会收敛到非常接近10的值,甚至可能在10附近震荡。
这就是因为MSE 对异常值非常敏感,它会过度惩罚离群点。大误差会被平方放大,这意味着离群点的大误差会产生巨大的梯度,将最优解 \(w\) 强行拉向离群点 \(w=6\) 的方向。为了平衡离群点的巨大损失,模型牺牲了主体数据的拟合精度,将最终的 \(w1\) 从10拉低到9左右。
MAE 对异常值具有鲁棒性,它更关注大多数样本。无论离群点的误差是 \(4x\) 还是 \(40x\),它产生的梯度大小都是较为固定的。
尽管在这个有离群值的案例中,MAE(绝对值项)得到了更接近真实主体数据的最优解,但在更一般的机器学习应用中,MSE(平方项)仍然是默认的首选
MSE 的平方项使得损失函数是一个处处可导的凸函数,为梯度下降等优化算法提供了最理想、最平滑的数学环境,保证了收敛的稳定性和速度。只有当数据中存在大量已知的、需要忽略的异常值时,才会考虑使用 MAE。
求导不可导
平方项是一个处处可导(Differentiable Everywhere)的平滑函数。它的导数在整个参数空间内都是连续的。
当误差很大时,梯度也很大,参数更新的步长就大(移动快)。
当误差很小时,梯度也趋于零,参数更新的步长就小(移动慢)。
梯度下降法等基于梯度的优化算法依赖于损失函数在每一点上都能求出明确且唯一的梯度。MSE 完美地满足了这一点,保证了算法的稳定和高效收敛。
当误差 \(y_i - \hat{y}_i\) 恰好等于0时(即模型预测完美),绝对值函数在该点是不可导的。在多维参数空间中,这会在损失曲面上形成一个尖锐的棱(而非平滑的底部)。
因此,选择 MSE 作为线性回归的损失函数,主要是因为它是一个处处可导且平滑的凸函数,这使得基于微积分的优化方法(如梯度下降法)能够高效、稳定、精确地找到全局最优解。