监督学习
这一章讲的是机器学习里最基础、也最重要的一种学习方式——监督学习(Supervised Learning)。你可以把它理解成"带着标准答案学习":我们给模型一堆"题目+答案",让它自己摸索出规律,以后再遇到新题目也能答对。学完这一章,你会搞懂模型的"输入-输出-参数"到底是什么意思,还会亲眼看到最最简单的模型——线性回归——是怎么被训练出来的。
什么是监督学习?
想象你是一个二手车贩子,想根据一辆车的车龄和行驶里程来估价。你手里有一堆历史成交记录:每辆车是什么情况、最后卖了多少钱。这就是一份"题目+答案"的题库。你希望从这些记录里总结出一条规律,以后来一辆新车,你报个价八九不离十。
这个过程就是监督学习。专业一点说:我们有一个输入 $x$(车龄、里程),一个输出 $y$(价格),想要找到一个函数 $f$,把输入变成输出:
$$y = f[x]$$当你拿输入 $x$ 去算输出 $y$ 的时候,这个动作叫推理(inference)——就是"用模型做预测"。
监督学习就像学生做练习册:题目是 $x$,标准答案是 $y$。学生(模型)反复做题、对答案、改错,最后学会了解题方法。而"没有答案的题"(比如高考真题)就是测试数据——用来检验学生是不是真的学会了,而不是把练习册背下来了。
模型与参数:一个公式家族
我们选的公式 $y = f[x]$ 并不是唯一的。公式里通常还藏着一些旋钮,叫参数,用 $\phi$ 表示。参数怎么拧,公式的行为就怎么变:
$$y = f[x, \phi]$$举个例子,直线的公式是 $y = \phi_0 + \phi_1 x$。这里 $\phi_0$ 是截距(直线和 $y$ 轴的交点),$\phi_1$ 是斜率(直线有多陡)。只要你愿意,可以拧出无数条不同的直线——所以这个公式其实代表了一个"直线家族",而参数 $\phi$ 决定了我们选家族里的哪一位成员。
最简单的模型:线性回归
假设我们只有 12 辆车的成交记录,横轴是车龄,纵轴是价格,散点图大概是从左上往右下掉的一团点。最朴素的猜想是:价格和车龄是直线关系,也就是用一条直线来拟合这些点:
$$y = \phi_0 + \phi_1 x$$问题来了:怎么判断哪条直线"最好"?光靠肉眼不够,我们需要一个打分器。
损失函数:模型的"考试分数"
对每个数据点,模型都会预测一个价格 $f[x_i, \phi]$,而真实成交价是 $y_i$。两者差得越多,说明这条线越不靠谱。把每个点的差距平方后加起来,就得到损失(Loss)——一个代表"模型有多差"的数字:
$$L(\phi) = \sum_{i=1}^{I} (f[x_i, \phi] - y_i)^2 = \sum_{i=1}^{I} (\phi_0 + \phi_1 x_i - y_i)^2$$因为这里用的是"差的平方和",所以叫最小二乘损失。为什么要平方?因为差值是正是负都算"错",平方后方向就无所谓了,而且大误差会被放大惩罚。损失越低,说明线拟合得越好。
于是"找最好的直线"变成了一个数学问题:
$$\hat{\phi} = \arg\min_{\phi} L(\phi)$$也就是:把参数拧到让损失最小为止。
损失函数就像投篮的"偏航记录":每个数据点是一次投篮,预测值离篮筐(真实值)多远,就记一个误差。把所有误差的平方加起来,就是一个总分数。我们想要的直线,就是那个"总偏差最小"的投篮姿势。
训练:一路"下山"找最低点
损失 $L$ 可以看成以参数 $\phi_0$、$\phi_1$ 为横纵坐标的"地形图":每个参数组合对应一个损失值,把损失画成高度,就得到一个碗状曲面。我们的目标,就是走到这个碗的最底端。
怎么走?从随机位置开始,朝最陡的下坡方向迈一步,然后重新看方向再迈一步,一直走到走不动为止(坡度变平了)。这个过程叫梯度下降(Gradient Descent)——"梯度"就是坡最陡的方向。
import numpy as np
# 训练数据:车龄 x,价格 y(虚构示例)
x = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
y = np.array([9.5, 8.3, 7.1, 6.0, 4.8, 3.9])
phi0, phi1 = 0.0, 0.0 # 参数初始值(随便挑一个起点)
lr = 0.01 # 学习率:每步迈多大
for step in range(2000):
pred = phi0 + phi1 * x
# 损失函数的梯度(对 phi0 和 phi1 求偏导)
grad0 = np.mean(2 * (pred - y))
grad1 = np.mean(2 * (pred - y) * x)
phi0 -= lr * grad0 # 朝反方向(下坡)更新参数
phi1 -= lr * grad1
print(f"截距 phi0 = {phi0:.2f}, 斜率 phi1 = {phi1:.2f}")
跑完这段代码,你就亲眼看到了一条直线被"训练"出来:参数从 $0$ 开始,一步步被梯度下降推到最优点。这就是后面所有深度学习训练的最基本原理。
测试与泛化:真本事还是死记硬背?
模型在训练数据上表现好,不代表真本事。万一它把练习册答案都背下来了,换道新题就露馅。所以训练完,我们要在没见过的测试数据上再考一次,看看它的泛化能力。
这里有两个常见的"翻车"姿势:
- 欠拟合(Underfitting):模型太简单,直线根本描述不了真实规律——就像学生只学了加减法就去考微积分。
- 过拟合(Overfitting):模型太能"记",把训练数据里的偶然噪声也当成了规律——就像学生把练习册页码都背下来,换个排版就不会了。