第一次接触机器学习,最容易被算法名称淹没:线性回归、神经网络、支持向量机、聚类……名字很多,但它们都在回答同一个问题:怎样从有限的数据中学出一套规律,并让这套规律在没见过的数据上继续有用?
这句话里有三个重点。我们手里只有有限数据;学到的是可计算的模型;最终要面对的是新样本。训练集上的漂亮分数只是过程指标,能否稳定处理新情况,才是机器学习真正关心的结果。
这一章先不急着推公式。我们会把机器学习的基本语言、三类学习方式、训练与评估闭环、泛化和数据泄漏连成一条线。读完后,你应该能做到下面几件事:
传统程序通常从规则出发。我们把业务规则写进代码,程序接收数据,再按规则计算答案。例如,会员消费满 300 元减 30 元,这条逻辑明确、稳定、容易验证,直接写条件判断就够了。
但有些任务很难把规则写全。假设我们要识别手写数字“8”。有人写得圆,有人写得扁,有人的两个圆圈甚至没有闭合。若靠人工列规则,我们很快就会遇到例外套例外。机器学习换了一种做法:给算法许多“图像—数字”样本,让它调整内部参数,找到从图像到数字类别的映射。

你可以用“任务、经验、表现”这三个问题判断学习是否真的发生:
如果模型接触更多有代表性的经验后,在相同评价标准下处理新邮件的能力提高了,我们才说它从数据中学到了东西。这里的“模型”不是一台机器,也不是完整应用,它是由数据和训练过程确定的一组计算关系。线上系统还包括数据采集、接口、监控、人工复核等部分。
机器学习也不等于整个人工智能。人工智能讨论如何让系统表现出感知、推理、规划和行动等能力,机器学习是其中一条以数据改进表现的技术路线。深度学习则主要指使用多层神经网络的一类机器学习方法。三者更像范围逐层收窄的关系,不能把“人工智能”“机器学习”“深度学习”当成三个并列算法。
一个问题通常在下面几项同时成立时更适合机器学习:
反过来,如果规则已经非常明确,或一次错误会造成无法接受的后果却又没有可靠复核机制,机器学习未必是合适的第一选择。数据也不会自动把模糊目标变清楚。“让用户更满意”还不是可训练任务,必须进一步落到可观察结果、时间窗口和约束条件上。
机器学习不是“把数据扔给算法”。它从问题定义开始:预测对象是谁,预测发生在什么时刻,结果给谁使用,错一次要付出什么代价。目标说不清,后面的模型分数越精确,越可能是在精确回答一个没用的问题。
算法不能直接理解“这套房交通方便、价格合理”。我们需要把现实对象变成可计算的记录。数据集中的一条记录通常叫一个样本或示例;描述样本的可用信息叫特征;希望模型预测的结果叫标签或目标。
以二手房成交价预测为例,一行数据可以写成这样:
如果任务是预测成交价,那么前四列是特征,成交价是标签。这一行整体是一个带标签样本。设第 个样本的特征向量为 ,标签为 ,一个监督学习数据集可以写成:
其中 是样本数量。把所有特征按行排起来得到特征矩阵 ,把标签排成一列得到向量 。以后你会频繁看到 model.fit(X, y),它表达的正是“用特征和对应标签训练模型”。

一列能不能当特征,取决于预测发生的时刻。假设我们要在用户下单前预测是否会退货,“最终退款金额”虽然存在于历史表里,却是在退货之后才知道。把它用作特征,相当于把未来答案塞给模型。离线分数会很好看,上线时却根本拿不到这列。
特征还要考虑表示方式。房屋面积可以直接用数值表示;片区名称属于类别信息,需要编码;照片、语音和文本则要变成数值张量或向量。表示不同,同一个学习算法看到的问题也会不同。
标签同样需要精确定义。“流失用户”究竟指 7 天没登录、30 天没购买,还是主动注销?三种定义会产生三套不同数据。标签常来自人工标注、业务事件或后续观测,每种来源都有噪声和偏差。
数据量大不等于数据有代表性。一百万条只覆盖夏季的天气记录,未必适合预测冬季降雨;一千万次活跃用户点击,也不能自动代表从不点击的人。先问样本覆盖了谁、漏掉了谁,再谈数量。
监督学习、无监督学习与强化学习的核心差别,是训练时能得到什么反馈。不要只背“有没有标签”,还要看问题是不是一次性预测,还是连续决策。
这三类是帮助入门的主框架,并不是互斥的算法清单。神经网络既能做监督分类,也能学习无标签表示,还能充当强化学习中的策略;生成式人工智能描述的是生成文本、图像等输出能力,其训练过程也可能组合自监督学习、监督微调和基于反馈的强化学习。判断学习方式时,应看数据和反馈,而不是模型名字。
监督学习拿到的是带标签样本 。模型根据特征做预测,再把预测与真实标签比较。常见任务有两类:
分类和回归的边界看输出含义,不看输入长什么样。输入都可以是图片:预测图片中商品的价格是回归,判断商品属于哪个品类是分类。
无监督学习通常只有特征 ,没有预先指定的标签 。它可以寻找相似样本形成的群组、压缩高维表示,或发现偏离主体的数据点。常见任务包括聚类、降维和部分异常检测方法。
聚类不等于分类。分类的类别在训练前已经定义,模型学习的是通往已知类别的边界;聚类产生的是数据结构,算法并不知道某个群组应该叫“高价值用户”还是“偶尔浏览者”。群组命名及其业务价值仍要由人结合上下文判断。
强化学习关心的是序列决策。智能体观察状态,选择动作,环境转移到新状态并给出奖励。学习目标是得到一个策略,使长期累计回报尽可能高。
它与监督学习的关键差别在于:环境往往不会告诉智能体“此刻唯一正确的动作是什么”,奖励还可能延迟出现。下棋时,一步棋当下没有标签,胜负可能几十步后才知道。智能体必须在探索新动作和利用已有经验之间取舍。

下面的交互把任务描述和学习方式放在一起。先自己判断,再查看反馈,尤其留意“已经有明确类别”和“想探索自然分组”的区别。
以监督学习为例,模型可以看成带参数的函数 。输入特征 后,它给出预测:
是模型参数。线性模型里的权重和偏置、神经网络里的连接权重,都属于参数。训练的工作,就是根据数据找到一组更合适的 。
先初始化参数。此时模型还没有从当前数据中学到规律,预测通常很差。
把一批训练样本送进模型,得到预测 。这一步叫前向计算。
若单个样本的损失记为 ,训练常常在最小化训练集平均损失:
这个式子没有保证模型真正理解了世界。它只表示模型在当前有限样本上的平均错误。若模型容量很大,它可能连噪声也一起记住,所以训练损失低并不是终点。
参数由训练数据和优化过程学出来;超参数由开发者在训练前设置或通过验证集选择。例如学习率、树的最大深度、正则化强度和聚类数量通常是超参数。我们不能看着最终测试集反复调超参数,否则测试集会逐渐变成另一个训练信号。
训练和推理是两个阶段。训练会读取历史数据并更新参数,成本通常较高;推理使用已经固定的参数对新输入计算结果。线上预测慢,不等于训练慢;训练分数高,也不等于线上预测可靠。
我们真正想要的,是模型对来自目标场景的新样本也有较小误差,这种能力叫泛化。训练数据只是未来世界的一份样本。如果模型只记住训练集中的偶然细节,换一批数据就会失效,这叫过拟合;如果模型连主要规律都没学到,训练集和新数据上都表现差,则更接近欠拟合。
可以把目标理解为降低真实场景中的期望风险:
难点在于我们不知道未来目标分布 的全貌,只能用独立数据估计。因此,数据划分不是整理文件的琐事,而是实验可信度的一部分。

70% / 15% / 15% 或 60% / 20% / 20% 都只是常见起点,不是定律。数据少时,可以在训练部分使用交叉验证来更充分地估计方案表现,同时仍保留独立测试集。数据很多时,较小比例也可能已经包含足够样本。关键是评估是否稳定、是否代表真实使用场景。
一个随机切分得到的高分,只能说明模型能处理“与随机抽出的训练样本相似的数据”。它未必能回答跨时间、跨人群或跨设备的泛化问题。
数据泄漏是指训练过程获得了在真实预测时不该拥有的信息。它常常不会让程序报错,反而会让评估分数异常漂亮,所以比普通代码错误更隐蔽。
最稳妥的顺序是:先划分,再只在训练数据上拟合任何会“学习数据统计量”的步骤,最后把已经拟合好的变换应用到验证集和测试集。 标准化、缺失值填补、类别编码、降维和特征选择都应遵守这个原则。使用管道可以把预处理和模型封装在一起,减少手工操作出错。
“测试阶段没有调用 model.fit”并不代表没有泄漏。如果标准化器、特征选择器或人工规则在全量数据上看过测试信息,测试集已经参与了训练方案。泄漏发生在整条数据流程,不只发生在模型拟合那一行。
下面的交互会展示切分顺序、重复样本和反复查看测试集怎样改变评估可信度。可以逐项打开风险开关,观察哪些“高分”其实不值得相信。
对每个特征和处理步骤,都问一句:在真实预测发生的那个时刻,我是否确实能获得完全相同的信息,并用同样方式计算它? 如果答案是否定或含糊,就先把它标成高风险,而不是急着塞进模型。
真正的项目很少从“选哪个算法”开始。更稳妥的顺序,是先把问题、数据和验收方式固定,再逐步增加模型复杂度。
定义预测时刻、输入对象、输出和使用者。把业务问题改写成明确任务,例如“在订单出库时,预测未来 48 小时内能否送达”。
选评价指标和最低可接受标准。指标要对应错误成本;垃圾邮件系统不能只看准确率,还要区分误拦正常邮件和漏掉垃圾邮件。
收集并审查数据。检查样本来源、标签定义、缺失、异常、重复、时间范围和覆盖人群,在任何学习型预处理前完成合适的数据划分。
建立简单基线。分类可以先比较多数类策略,回归可以先用训练集均值。基线告诉我们复杂模型是否真的带来增量。
模型指标也不是产品结果本身。更高的离线 AUC 不保证用户体验一定变好;上线还会受到延迟、界面、策略阈值和反馈回路影响。机器学习工作流的终点不是保存一个模型文件,而是让整个系统在约束下持续产生可验证的结果。
一个好基线很朴素:它容易复现、含义清楚、能快速暴露数据和指标问题。先超过简单基线,再讨论复杂结构,通常能省下大量无效实验。
下面用鸢尾花数据做三分类。每个样本有花萼、花瓣的长度和宽度四个特征,标签是三个花种之一。这个例子的目的不是追求最高分,而是把“切分—预处理—训练—验证—最终测试”跑通。
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
#步骤一:读取特征 X 和标签 y
X, y = load_iris(return_X_y=True)
#步骤二:先留出最终测试集;stratify 保持类别比例大致一致
X_dev, X_test, y_dev, y_test = train_test_split(
这段代码里有几个容易忽略的细节:
random_state=42 固定随机切分,便于复现,不代表 42 有特殊统计意义;stratify=y 适用于这里的分类任务,可以减小小数据集各集合类别比例波动;StandardScaler 和模型放在同一管道,调用 fit 时只从训练集学习标准化参数;实际项目还要保存数据版本和模型配置,并根据业务风险选择指标。若我们尝试多个正则化强度,应根据验证集或训练部分的交叉验证选择,选择完成后再碰测试集。
把 LogisticRegression 的 C 分别改成 0.01、0.1、1、10,只记录验证集结果。先选出方案,再查看一次测试集。思考:如果四个方案的验证分数完全一样,你还会考虑哪些因素?
可以比较不同随机切分或交叉验证下的稳定性、模型复杂度、训练和推理成本,以及各类别的混淆情况。不要为了制造差异而反复查看测试集;测试集的职责是估计冻结方案的泛化表现。
到这里,我们已经有了一张完整地图。最后把几个常见误区集中拆开,免得后续学到复杂模型时又绕回来。
后续内容可以按四条线来理解,而不必把每个算法当成孤立知识点:
学习时建议始终带着同一组问题:输入 是什么,目标 是什么;模型输出什么;损失或评价指标是什么;哪些信息只能在训练阶段使用;最终要泛化到谁。只要这几个问题能答清楚,算法再复杂,也仍然落在这一章建立的框架里。
现在最合适的下一步不是继续背术语,而是进入线性回归:用一个足够简单的模型,看清预测函数、损失、参数更新和泛化怎样在代码与公式中对应起来。
用损失函数比较预测与真实标签。回归可以计算预测值与真实值的距离,分类可以衡量模型给真实类别的概率是否足够高。
优化算法根据损失调整参数,使下一轮在训练数据上的平均损失倾向于下降。
重复多轮,并在独立验证数据上观察表现。训练结束后固定参数,用模型处理新样本,这一阶段叫推理或预测。
用训练集拟合,用验证集比较方案。一次只改变少量因素,记录数据版本、随机种子、参数、指标和代码版本,保证结果能够复查。
做错误分析。不要只看一个总分,要检查模型在哪些人群、时间段、类别或输入质量下失败,并判断问题来自数据、标签、表示、模型还是评价方式。
冻结方案后评估测试集。达到要求才进入部署;上线后继续监控输入分布、延迟、错误成本和反馈回路,必要时回滚或重新训练。