前言这份「序章」不写花哨的模型只把机器学习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 randomrandom.seed(0)# 1) 造一批带噪声的数据真实关系是 y 3x 2w_true, b_true 3.0, 2.0xs [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 bdef mean_squared_error(w, b, xs, ys):# 均方误差对每个样本的 (预测 - 真实) 平方求平均total 0.0for x, y in zip(xs, ys):err predict(w, b, x) - ytotal err * errreturn 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.0for x, y in zip(xs, ys):err predict(w, b, x) - ygw 2 * err * x / ngb 2 * err / nreturn gw, gbw, 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 * gbif epoch % 50 0:print(fepoch{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在验证集上比较提不上去再换复杂模型。❌ 训练损失一直降就以为成功了。 ✅ 同时看验证集损失训练损失降、验证损失升就是过拟合需要正则化、加数据或简化模型。❌ 把标签、文件名、序号之类的「答案泄漏特征」当普通特征喂进去。 ✅ 逐个检查特征在预测时是否可得、是否与标签同源可疑的直接删除再对比验证集表现。总结环节一句话要点任务类型分类还是回归先定清楚特征决定模型能看到什么收益最高数据划分训练/验证/测试分离变换只在训练集拟合训练最小化损失梯度下降 学习率调参在验证集上做别碰测试集评估类别不平衡时准确率会骗人机器学习的门槛不在数学而在「严谨地做对比」每一次改动都要有一个没被污染过的集合来评判它。序章的任务就是建立这个纪律下一篇再具体进入某个算法族。入门阶段请务必记住两条一是先有流程再谈模型二是任何没在独立数据上验证过的结论都不算结论。