前言
这份「序章」不写花哨的模型,只把机器学习(machine learning)这件事的骨架讲清楚:它到底在解决什么类型的问题、一个完整流程由哪几个环节组成、术语之间是什么关系。把骨架搭稳,后面再看 scikit-learn、PyTorch、TensorFlow 的文档,才不会觉得全是黑话。
一个常见的误解是「机器学习 = 调一个库」。库确实只是最后一公里:真正决定结果的是数据怎么划分、特征怎么构造、指标怎么选。另一个误解是「必须先学完高等数学才能动手」。事实是入门阶段用到的数学非常有限:会算平均数、理解「斜率」和「导数表示变化率」就够跑通一个线性回归;更深的推导可以边用边补。
还有一点必须说在前面:本文给出的代码没有在本机运行过,本机也没有安装 Python 解释器与任何第三方库。文中凡是涉及 scikit-learn、PyTorch 这类第三方库的地方,只讲流程位置与作用,具体函数签名以各自官方文档为准;凡是纯标准库的示例,都是逐行推演过的、可以直接复制运行的最小骨架,但同样未在真实解释器上执行。
一、机器学习在替代什么
传统程序是「人写规则,程序执行规则」。比如判断一封邮件是不是垃圾邮件,人写下「标题含『中奖』就判为垃圾」这样的规则。规则一多就打架,而且写规则的人永远追不上对方改话术的速度。
机器学习的做法是反过来:人给出「输入 → 正确答案」的样例(样本,sample),让算法自己去找规则(模型,model)。再遇到新的输入,模型按学到的规则给出预测(prediction)。所以机器学习的输入不是规则,是数据;输出不是答案,是「能给出答案的函数」。
由此可以推出几个必然结论,它们解释了后面所有环节存在的理由:
- 数据里有噪声、有偏、有缺,模型就会把这些一起学走,这叫过拟合(overfitting)。
- 模型只在见过的数据分布上可靠,换一批数据就未必,所以要留一部分数据不参与训练,专门用来「假装没见过」。
- 规则是概率性的,所以输出通常需要配合一个评价指标,而不是「对/错」两个字。
二、监督学习的基本环节
入门阶段绝大多数任务属于监督学习(supervised learning):每个样本都带一个已知的正确答案(标签,label)。它的流程固定,按顺序是下面六步。
1. 明确任务类型。标签是离散的类别(垃圾/正常、猫/狗)叫分类(classification);标签是连续数值(房价、销量)叫回归(regression)。任务类型决定了后面用什么损失函数与什么指标,这一步定错,后面全错。
2. 特征工程(feature engineering)。原始数据要变成数值向量。文本要分词与向量化,类别要编码,量纲差异大的列要标准化。特征决定了模型能看到什么,通常是收益最高的一步。
3. 数据划分。至少要切成训练集(training set)与测试集(test set);做调参时还要从训练集里再切一份验证集(validation set)。三条铁律:测试集在最终评估前一次都不能看;标准化、缺失值填充这类会「从数据里学参数」的步骤,必须只在训练集上拟合、再作用到其他集合;切分要随机且保持类别比例(分层抽样,stratified sampling)。
4. 选模型与训练。训练就是在找一组参数,让某种「错得多离谱」的度量(损失,loss)尽量小。最小化的通用手段是梯度下降(gradient descent):算损失对参数的梯度(偏导数),沿梯度反方向挪一小步,反复迭代。步长叫学习率(learning rate),太大会震荡发散,太小会慢到看不出进展。
5. 在验证集上调超参数。学习率、正则化强度、树的深度这类「模型自己学不出来、要人来定」的量叫超参数(hyperparameter)。在验证集上试,不要用测试集试。
6. 在测试集上报告结果。只报一次,并且指标要选对。
三、评价指标:准确率在类别不平衡时会骗人
这是序章里最该记住的一段。准确率(accuracy)= 预测正确的样本数 / 总样本数,它把「把多数类全猜一遍」这种什么都不学的做法也可能给出很高的分数。
反例可以推演清楚:假设一千个样本里绝大多数是负类、只有极少数是正类,那么一个永远输出「负类」的模型,它的准确率就等于负类所占的比例——看上去很高,可它一个正类都抓不到。如果正类是欺诈交易或病症,这个模型毫无价值。
所以要看混淆矩阵(confusion matrix)的四个格子,并由此定义:
| 指标 | 关注点 | 典型场景 |
|---|
| 准确率 accuracy | 整体命中比例 | 类别大致均衡时 |
| 精确率 precision | 判为正的里面有多少真的是正 | 误报代价高(垃圾邮件误杀) |
| 召回率 recall | 真正的正类里抓到了多少 | 漏报代价高(疾病筛查) |
| F1 | 精确率与召回率的调和平均 | 需要单一综合分时 |
精确率与召回率通常此消彼长:把判定阈值调高,判为正的变少、更准,但漏掉的变多。所以「只看一个数」往往会做出错误决策,报告结果时应当把类别分布和所用的指标一起写出来。
四、入门路线的取舍
| 阶段 | 工具 | 什么时候用 | 代价 |
|---|
| 打基础 | 纯标准库手写 | 理解梯度下降、损失 | 只能做玩具规模 |
| 表格数据 | scikit-learn | 结构化数据、经典算法 | 不擅长图像与超大数据 |
| 深度学习 | PyTorch / TensorFlow | 图像、语音、文本 | 环境重、需要 GPU 更顺 |
建议按「先用 scikit-learn 把一条完整流程跑通,再上深度学习」的顺序走。深度学习不是「更高级的机器学习」,它只是模型族里的一支,表格数据上未必赢过梯度提升树。
下面这段示例用纯标准库把「梯度下降」这件事写出来,不依赖任何第三方库,是把上面第 4 步落到实处的骨架。
# 适用于 Python 3.8+
# 用一维线性回归 y = w * x + b 演示梯度下降,只用标准库
import random
random.seed(0)
# 1) 造一批带噪声的数据:真实关系是 y = 3x + 2
w_true, b_true = 3.0, 2.0
xs = [i * 0.1 for i in range(-20, 21)] # 特征
ys = [w_true * x + b_true + random.uniform(-0.2, 0.2) for x in xs] # 标签
def predict(w, b, x):
return w * x + b
def mean_squared_error(w, b, xs, ys):
# 均方误差:对每个样本的 (预测 - 真实) 平方求平均
total = 0.0
for x, y in zip(xs, ys):
err = predict(w, b, x) - y
total += err * err
return total / len(xs)
def gradients(w, b, xs, ys):
# dL/dw = 2 * mean((pred - y) * x),dL/db = 2 * mean(pred - y)
n = len(xs)
gw = gb = 0.0
for x, y in zip(xs, ys):
err = predict(w, b, x) - y
gw += 2 * err * x / n
gb += 2 * err / n
return gw, gb
w, b = 0.0, 0.0 # 参数从 0 开始
lr = 0.05 # 学习率
for epoch in range(200):
gw, gb = gradients(w, b, xs, ys)
w -= lr * gw # 沿梯度反方向走一小步
b -= lr * gb
if epoch % 50 == 0:
print(f"epoch={epoch:3d} loss={mean_squared_error(w, b, xs, ys):.6f} w={w:.4f} b={b:.4f}")
print(f"学到的 w={w:.4f} b={b:.4f},真实值 w={w_true} b={b_true}")运行后你会看到损失值逐轮变小、w与b逐渐靠近 3 和 2 ——具体数值取决于随机种子、学习率和迭代次数,这里不给出任何实测数字。把lr改成 1.5 再跑,通常能看到损失震荡甚至变成inf,这就是「学习率过大」的直观表现。
常见坑点
❌ 用测试集反复调参,看到分数涨了就留下这个版本。 ✅ 测试集只在最后用一次;调参在验证集上做,必要时用交叉验证(cross-validation)降低验证集划分的偶然性。
❌ 在全部数据上做标准化和缺失值填充,然后才切分训练集与测试集。 ✅ 只在训练集上fit这些变换,再transform到验证集与测试集,否则测试集的信息泄漏(data leakage)进了训练。
❌ 类别不平衡时只看准确率,报出很高的分数就认为模型可用。 ✅ 先看混淆矩阵与各类别样本数,按业务选精确率、召回率或 F1,并明确说明用的哪一个。
❌ 以为「模型越复杂效果越好」,一上来就上深度学习。 ✅ 先用简单模型建立基线(baseline),在验证集上比较;提不上去再换复杂模型。
❌ 训练损失一直降就以为成功了。 ✅ 同时看验证集损失;训练损失降、验证损失升,就是过拟合,需要正则化、加数据或简化模型。
❌ 把标签、文件名、序号之类的「答案泄漏特征」当普通特征喂进去。 ✅ 逐个检查特征在预测时是否可得、是否与标签同源,可疑的直接删除再对比验证集表现。
总结
| 环节 | 一句话要点 |
|---|
| 任务类型 | 分类还是回归,先定清楚 |
| 特征 | 决定模型能看到什么,收益最高 |
| 数据划分 | 训练/验证/测试分离,变换只在训练集拟合 |
| 训练 | 最小化损失,梯度下降 + 学习率 |
| 调参 | 在验证集上做,别碰测试集 |
| 评估 | 类别不平衡时准确率会骗人 |
机器学习的门槛不在数学,而在「严谨地做对比」:每一次改动都要有一个没被污染过的集合来评判它。序章的任务就是建立这个纪律,下一篇再具体进入某个算法族。
入门阶段请务必记住两条:一是先有流程,再谈模型;二是任何没在独立数据上验证过的结论都不算结论。