本文是机器学习模型训练的入门讲解。先给出训练的总体框架,再按框架的步骤逐一讲其中的名词和方法。每个词先说它是什么,再举一个日常的例子。
全文主要用一个例子贯穿:识别垃圾邮件。模型读一封邮件,判断它是不是垃圾邮件。
怎么记
- 先记框架,不要先背词。 第一节的六个步骤是骨架,所有名词都挂在某一步上。碰到一个新词,先想它属于哪一步、要解决什么问题。
- 再记第二节的 12 个核心词。 能把这 12 个词讲清楚,就能听懂大部分讨论。其余的词用到时再回来查。
- 每个词配一个例子。 「特征是输入」不好记;「邮件里有没有『中奖』两个字就是一个特征」好记。
- 讲给别人听。 合上文档,用自己的话把六个步骤讲一遍。卡住的地方就是没懂的地方。最后一节的自测题可以拿来练。
一、总体框架
六个步骤
几乎所有模型训练项目都按这六步走:
| 步骤 | 做什么 | 要回答的关键问题 | 详见 |
|---|---|---|---|
| 1. 定义任务 | 确定模型输入什么、输出什么 | 是分类还是回归?怎样才算做成功? | 第三节 |
| 2. 数据和标注 | 收集样本,给每个样本定好标准答案 | 数据够不够?答案准不准? | 第四节 |
| 3. 预处理 | 把原始数据整理成统一的格式,再用探索性分析把数据看一遍 | 不同来源的数据怎么统一?数据有没有明显的问题? | 第五节 |
| 4. 数据划分 | 分出训练集、验证集和测试集 | 测试的数据有没有提前漏给模型? | 第六节 |
| 5. 训练 | 先做简单的基线模型,再试复杂模型 | 模型是学到了规律,还是只背下了练习题? | 第七节、第十一节 |
| 6. 评估 | 用测试集或交叉验证检验模型 | 哪种错误代价更大?换一批数据还准吗? | 第八节 |
模型做好、投入使用以后,还要持续检查效果,见第九节。
这六步通常要来回走好几轮。评估结果不理想时,最常见的做法是回到第 2 步补数据或修正标签,而不是只换一个更复杂的模型。
不同项目差在哪
骨架都一样,差别在每一步的具体做法上:
- 标签从哪来:有的现成,比如用户有没有点「举报垃圾邮件」;有的要专家来标,比如医生判读片子,又贵又慢。
- 预处理怎么做:跟数据类型走,表格、文本、图像各不相同。
- 用什么模型:跟数据量走,数据少用简单模型,数据多才用深度学习。
- 看什么指标:跟业务代价走,看漏判和误判哪个后果更严重。
工具反而是最容易换的部分。
打个比方:学生备考
六个步骤可以对应到学生备考:
- 先收集很多道已知答案的题。每道题叫一个样本,题目部分叫特征,答案叫标签(第 2 步)。
- 把题目整理成统一的格式,这一步叫预处理(第 3 步)。
- 把题分成两堆:一堆给学生练习,叫训练集;另一堆锁起来当期末考试,叫测试集(第 4 步)。
- 学生就是模型。它反复做练习题、对答案、改正自己的思路,这个过程叫训练(第 5 步)。
- 期末用测试集考一次,看它答对多少,这叫评估(第 6 步)。
有两种情况说明学生没学好:
- 只会背练习题的答案,换一道新题就不会,叫过拟合;
- 偷看过考题,所以分数虚高,叫数据泄露。
二、核心 12 个词
| 名词 | 是什么 | 垃圾邮件的例子 |
|---|---|---|
| 样本 | 一个用来学习的例子 | 一封邮件 |
| 特征 | 交给模型做判断的输入 | 发件人是否陌生、有没有「中奖」字样、链接有几个;也可以直接是邮件全文 |
| 标签 | 样本的标准答案 | 「垃圾邮件」或「正常邮件」 |
| 模型 | 根据特征算出答案的一套规则,规则的细节是从数据里学出来的 | 输入一封邮件,输出「是垃圾邮件的概率」 |
| 训练 | 让模型看大量样本,不断调整自己,直到答得尽量准 | 用一万封已标好的邮件训练 |
| 训练集 | 给模型学习用的样本 | 其中八千封 |
| 测试集 | 训练时不给模型看,最后用来检验的样本 | 另外两千封 |
| 过拟合 | 模型把训练数据里的巧合当成规律,换一批数据就不准 | 训练集里垃圾邮件碰巧都在周一发,模型就把「周一发的」当成垃圾邮件的特征 |
| 数据泄露 | 测试时用到的信息在训练中漏给了模型,分数虚高 | 同一封群发邮件的副本既在训练集又在测试集,模型只是背下了它 |
| 基线模型 | 先用简单方法做出的模型,作为后续比较的起点 | 「含『中奖』就判垃圾」这条规则,或者一个简单的逻辑回归 |
| 深度学习 | 用多层神经网络直接从原始数据(文字、图像、声音)里学规律的方法 | 直接读邮件全文,不用人工设计特征 |
| AUC | 衡量模型把两类分开的能力,0.5 是瞎猜,1 是全对,低于 0.5 说明把两类弄反了 | 随机抽一封垃圾邮件和一封正常邮件,模型给垃圾邮件打的分更高的机会有多大 |
三、第 1 步:定义任务
定义任务就是在动手之前想清楚三件事:模型输入什么,输出什么,做到什么程度算成功。比如垃圾邮件任务:输入一封邮件,输出它是垃圾邮件的概率;成功的标准是拦下九成以上的垃圾邮件,同时误拦的正常邮件不超过百分之一。
学习方式
学习方式是按「标签从哪来」给训练方法分类,分三种:
- 监督学习:每个样本都有人给的标签,模型照着答案学。
- 无监督学习:没有标签,任务本身也没有标准答案,模型自己在数据里找规律,结果要靠人解读。
- 自监督学习:标签从数据本身自动造出来,比如遮住句子里一个词让模型猜,被遮住的词就是答案。这样不用人标注,海量数据都能拿来学,大语言模型的预训练就是这样做的。
一句话区分:监督是「老师出题」,无监督是「没有题,自己找规律」,自监督是「自己给自己出题」。
同一个项目常常组合几种学习方式。比如先用自监督学习在大量无标签数据上预训练,再用监督学习在少量有标签数据上微调,见第七节的「预训练」和「微调」。
任务类型
任务类型是按「模型要输出什么」给问题分类。先认清任务类型,才知道该用什么模型和指标。
| 类型 | 输出什么 | 例子 | 通常的学习方式 |
|---|---|---|---|
| 分类 | 一个类别 | 判断一封邮件是不是垃圾邮件;判断一张照片里是猫还是狗 | 监督 |
| 回归 | 一个数值 | 预测一套房子的售价;预测明天的气温 | 监督 |
| 分割 | 图像上每个像素属于哪一类,也就是把目标的轮廓描出来 | 把街景照片里每个像素标成道路、车辆或行人 | 监督。每个像素都要人标,标注最费力 |
| 检测 | 目标的位置和类别,用方框框出来 | 在监控画面里框出每一个人 | 监督。人要先画好方框 |
| 聚类 | 把相似的样本分成几组 | 按购物习惯把客户自动分组 | 无监督 |
| 生成 | 新的文字、图像等 | 根据前文续写一段话;根据文字描述画一张图 | 自监督为主,比如根据前文猜下一个词 |
分割和检测容易混:检测只画一个方框,分割要把轮廓精确描出来。需要算面积或体积时,必须用分割。
任务类型还决定了用什么评估指标。评估指标是一种打分规则,用来比较模型的输出和标准答案差多少。输出是什么东西,就只能用对应的方法比:
| 任务类型 | 输出 | 能怎么比 | 常用指标 |
|---|---|---|---|
| 分类 | 一个类别 | 只有对和错,没有「差一点」 | 准确率、召回率、AUC |
| 回归 | 一个数 | 看差了多少 | 平均绝对误差(MAE) |
| 分割 | 一块区域 | 看和标准答案重合了多少 | Dice 系数 |
用错指标会得出错误的结论。比如明天实际是 25 度,如果按对错给回归模型打分,预测 25.3 度和预测 5 度都算错,分不出好坏。各个指标的含义见第八节。
回归是什么
回归在机器学习里就是预测一个数,最常见的做法是找一条最贴近数据的线。比如收集 100 套房子的面积和售价画在图上,大致是面积越大、价格越高;回归就是在这堆点中间画一条线,让它离所有点都尽量近。来了一套没见过的房子,看它的面积在线上对应多少价格,就是预测值。这条线可以写成一句话:「面积每多 1 平方米,房价多 5 万元」。特征多时道理一样,只是同时考虑面积、楼层、地段等好几个因素,每个因素一个权重。
「回归」这个名字本身没有含义,是历史遗留的。19 世纪英国学者高尔顿研究父母和子女的身高,发现特别高的父母,孩子通常也高,但没有父母那么高;特别矮的父母,孩子通常也矮,但没有父母那么矮。孩子的身高会往人群的平均值靠拢,他把这叫「回归到平均值」。他描述这种关系时在数据上画的线,后来就沿用了「回归」这个名字,即使用来预测房价、气温,和身高无关了也一样。逻辑回归中间那一步也是在画这种线,所以名字里带「回归」,见第七节。
四、第 2 步:数据和标注
- 数据集:一批样本的集合。
- 标注:给样本定标签的工作。有的标签现成(用户有没有点「举报垃圾邮件」),有的要专家来标(医生判读片子),后者又贵又慢。
标注质量
标注质量指标签本身有没有错。标签错得多,模型照着错误答案学,也很难做得更好。
一致率是最直接的衡量办法:两个人分别标注同一批样本,看结论相同的比例。比如两人判断同一批邮件,有一成判得不一样,说明标签本身就有一成左右的不确定。
但两类数量相差大时,一致率会偏高。九成都是正常邮件时,两人闭着眼都判「正常」,也有九成一致。所以常改用 Kappa 系数,它从一致率里扣掉碰巧一致的部分,算法是:
Kappa =(实际一致率 − 碰巧一致率)÷(1 − 碰巧一致率)
比如 100 封邮件,两人的标注如下:
| 乙标垃圾 | 乙标正常 | |
|---|---|---|
| 甲标垃圾 | 6 | 4 |
| 甲标正常 | 4 | 86 |
- 实际一致率:两人结论相同的有 6 + 86 = 92 封,是 92%。
- 碰巧一致率:两人各把 10% 的邮件标成垃圾、90% 标成正常。如果互不相干地乱标,同时标垃圾的概率是 10% × 10% = 1%,同时标正常的概率是 90% × 90% = 81%,合计 82%。
- Kappa:(92% − 82%)÷(100% − 82%)≈ 0.56。分母是扣掉碰巧部分后还能争取的 18 个百分点,两人只多争取到 10 个。
92% 的一致率听起来很高,Kappa 却只有中等水平。Kappa 的常用经验分档:
| Kappa | 一致程度 |
|---|---|
| 小于 0 | 比乱标还差,通常是两人对标准的理解相反 |
| 0 到 0.2 | 很差,0 表示和碰巧一样 |
| 0.2 到 0.4 | 一般 |
| 0.4 到 0.6 | 中等 |
| 0.6 到 0.8 | 较好 |
| 0.8 到 1 | 几乎完全一致,1 表示完全一致 |
二分类的几个词
二分类是只分两类的分类任务。垃圾邮件任务就是二分类,两类是垃圾邮件和正常邮件。
- 阳性、阴性:两类里「要找出来的那一类」叫阳性,另一类叫阴性。垃圾邮件任务里,垃圾邮件是阳性,正常邮件是阴性。
- 多数类、少数类:两类里数量多的叫多数类,数量少的叫少数类。比如一万封邮件里有九千五百封正常邮件、五百封垃圾邮件,正常邮件是多数类,垃圾邮件是少数类。
- 类别不平衡:两类数量相差很大,比如上面的 9500 比 500。这时模型容易偷懒,把所有邮件都判成正常邮件,准确率也有 95%,但一封垃圾邮件都没找出来。需要专门处理:评估时不能只看准确率,见第八节;判断时阈值要另定,不能默认用 0.5。也可以在训练时用第七节的「类别加权」,但它有代价。
五、第 3 步:预处理
预处理是把原始数据整理成模型能用的统一格式。数据类型不同,预处理的方法差别很大,这也是不同项目之间差别最大的一步。
通用操作
- 数据清洗:去掉重复、明显错误的样本。比如删掉重复的群发邮件。
- 缺失值处理:有的样本缺了某个特征时,要么删掉这个样本,要么用平均值等方式补上。
- 归一化、标准化:把不同特征的数值换算到相近的范围。归一化是把数值缩放到 0 到 1 之间;标准化是把数值换算成「比平均值高或低多少」。
- 为什么要换算:比如「链接数」是 0 到 20,「邮件字数」是 0 到 5000。不换算的话,加了惩罚的逻辑回归、神经网络这类模型会被数值范围带偏,比如 LASSO 会因为特征的数值大小不同而罚得不公平,所以用 LASSO、Ridge 前必须先标准化;
- 哪些不用换算:决策树、随机森林只比大小,不受影响。
- 编码:把文字类的特征变成数字。比如把「发件人类型」的「陌生人、同事、商家」变成 0、1、2,或者拆成「是不是陌生人」「是不是同事」「是不是商家」三个是否题。
- 特征工程:人工设计、计算新特征的过程,比如从邮件里数出感叹号的个数。医学影像上的特征工程叫影像组学,用程序从病灶里批量算出几百个描述亮度、形状和纹理的数。深度学习大大减少了这部分工作。
按数据类型的特有操作
| 数据类型 | 常见操作 |
|---|---|
| 表格 | 清洗、补缺失值、编码、标准化 |
| 文本 | 分词:把句子切成词或更小的单位,这些单位在大语言模型里叫 token;去掉无意义的符号 |
| 普通图像 | 缩放到统一大小、调整亮度 |
| 医学影像 | 格式转换、配准(把不同时间、不同设备拍的片子对齐)、亮度标准化 |
探索性分析:训练前先看数据
探索性分析(Exploratory Data Analysis,简称 EDA)是在训练模型之前,不建任何模型,只用图表和简单统计把数据看一遍。它通常在预处理之后、数据划分之前做,因为要等特征都算出来才有东西可看。
为什么要先看:模型不会告诉你数据有问题,它只会照单全收。比如一批邮件里混进了重复的群发邮件,或者有一部分标签贴反了,模型照样能训练出一个分数,只是这个分数不可信。这类问题在训练前看一眼图表就能发现,等模型结果出来再查就难多了。
常做三件事:
- 看每个特征的分布,找异常值:比如画出邮件字数的分布图,发现有字数为负数的邮件,或者一封几十万字的邮件,多半是数据录入或抓取出了错。
- 按类别比较两组的基本情况:把垃圾邮件和正常邮件分开,列一张表比较它们的来源、收集时间、语言等。临床研究里这张表叫基线特征表,论文里通常是「表 1」。它最重要的用途是发现混杂,也就是和答案无关、却恰好和答案对得上的差别。比如垃圾邮件都是 2020 年收集的,正常邮件都是 2024 年收集的,模型就可能靠「邮件格式像哪一年」来判断,而不是靠内容。
- 逐个看特征和答案的关系:比如画箱线图,看垃圾邮件的链接数是不是普遍比正常邮件多;也可以只用这一个特征给邮件排序,算一个 AUC。临床研究里,这样一次只看一个特征的比较叫单因素分析。
有两条规矩:
- 结果只作参考,不用来挑特征:探索性分析用的是全部数据,包括以后要当考题的那部分。看完结果再决定模型用哪些特征,等于先看了考题,见第六节「数据泄露的常见形式」。要用哪些特征,最好按专业知识事先定好。
- 不要同时比太多特征:比一百个特征,总有几个碰巧显得差别很大。
它和第 5 步的基线模型都会看「特征能不能区分两类」,区别在于:探索性分析一次看一个特征,不学习任何东西,重点是检查数据有没有问题;基线模型把几个特征合起来,从数据里学权重,要用交叉验证检验,重点是做出一个能用的判断工具。
六、第 4 步:数据划分
- 训练集、测试集:见第二节。
- 验证集:从训练数据里再分出一小份,训练过程中用来选设置、判断何时停止。它和测试集的区别是:验证集在训练中反复使用,测试集只在最后用一次。
- 常见比例:数据多时按 70%、15%、15% 分成训练集、验证集、测试集,或者其他相近的比例。不单独留验证集时,常按 80%、20% 分成训练集和测试集,第二节的例子就是这样分的。
- 按组划分:同一个来源的样本,要么全部放进训练集,要么全部放进测试集,不能拆开。比如同一个病人的多次检查、同一个用户的多条记录。否则模型可能只是「认出了这个人」,并没有学会判断。
- 按时间划分:用较早的数据训练,较晚的数据测试。这最接近真实使用的情况,因为模型上线后面对的总是未来的数据。
- 分层划分:按标签比例切分,见下文。
- 交叉验证、嵌套交叉验证:数据少时轮流当考题的划分方法,见下文。
分层划分
分层划分是划分数据时,先按标签把样本分成几堆,每一堆各自按同样的比例切开。这样每一份里垃圾邮件和正常邮件的比例都和总体一致。比如 500 封垃圾邮件、9500 封正常邮件按 80%、20% 划分:
| 垃圾邮件 | 正常邮件 | 合计 | |
|---|---|---|---|
| 训练集 | 400 | 7600 | 8000 |
| 测试集 | 100 | 1900 | 2000 |
不分层、直接随机切的话,测试集里的垃圾邮件可能是 80 封,也可能是 120 封;数据少时,某一份里甚至可能一封都没有。分层划分和按组划分可以同时使用。
交叉验证
交叉验证是把数据分成 5 份,轮流用 4 份训练、1 份检验,重复 5 次,把 5 次的分数取平均。数据少时,这样每个样本都能当一次考题,结果更稳定。
打个比方:把题库分成 5 套卷子,轮流拿一套当期末、其余四套当练习,考 5 次取平均。
它和「一次切成 80%、20%」一样,回答的是「哪些样本当考题」,所以归在划分这一步。但它的用途是评估,切好以后要把第 5 步训练和第 6 步评估重复做 5 遍。也就是说,怎么分卷子是划分的事,平均分是评估的事。
数据少、又要调超参数时,要在交叉验证里面再套一层交叉验证,叫嵌套交叉验证,见下一小节。
嵌套交叉验证
嵌套交叉验证分两层,各管一件事:
- 外层负责打分,相当于期末考试,回答「这套做法最终有多准」;
- 内层负责挑设置,相当于期末前的模拟考,回答「用哪个超参数最好」。

以 100 个样本、要在弱、中、强三种设置里挑一个为例:
- 外层把 100 个样本分成 5 份,每份 20 个。第 1 轮拿第 1 份当考题,剩下 80 个交给内层。
- 内层只在这 80 个里做:再分成 5 份,每份 16 个。弱、中、强三种设置各做一遍普通的交叉验证,选平均分最高的,比如「中」。
- 回到外层:用「中」在 80 个上训练,再在 20 个考题上打分。
- 外层 5 轮都这样做,5 个分数的平均就是最终成绩。
为什么要分两层:如果只用一层交叉验证,又用它挑设置、又用它报成绩,就相当于看了考题再挑复习方法,分数会偏高。比如三种设置的真实水平都是 AUC 0.75,交叉验证因为随机波动,测出 0.72、0.75 和 0.79。挑出 0.79 那个并报告它,多出的 0.04 是运气,不是本事;试的设置越多,越容易挑到运气好的那一个。分两层后,挑设置时从来不碰外层的考题,外层的分数就不会被挑选这一步抬高。
每轮外层选出的设置可能不同,这没关系,因为外层评估的是「先挑设置、再训练」这一整套做法。评估完以后,用全部数据再挑一次设置、训练一次,得到最终交付的模型;外层的成绩就是对它准确度的估计。
嵌套交叉验证要训练很多次:上面的例子是 5 × (3 × 5 + 1) = 80 次。简单模型每次几秒,没问题;深度学习每次要几小时,所以数据多时通常改为单独留出验证集和测试集。
什么时候用哪种
选哪种划分方法,看两个问题:数据够不够多,能不能单独锁一份测试集;要不要挑超参数。下表的样本数只是大致的分界:
| 情况 | 用什么 |
|---|---|
| 数据多,几千个以上 | 直接分成训练集、验证集、测试集 |
| 数据中等,几百个 | 先锁一份测试集,在其余数据上用交叉验证挑超参数 |
| 数据少,超参数事先定死 | 普通交叉验证,只用来打分 |
| 数据少,还要挑超参数 | 嵌套交叉验证 |
数据泄露的常见形式
数据泄露是考题的信息提前漏给了模型,测试分数会虚高,而且测试集本身发现不了。下面几种最常见,划分数据和写代码时逐条对照:
| 形式 | 例子 | 怎么避免 |
|---|---|---|
| 同一来源的样本分在两边 | 同一个用户的多条记录、同一个病人的多次检查,一部分在训练集、一部分在测试集 | 按组划分 |
| 预处理用了全部数据 | 标准化用的平均值、补缺失值用的平均值,是在全部数据上算的,里面含有测试集的信息 | 这些统计量只用训练集算,再拿去套测试集 |
| 特征筛选用了全部数据 | 先用全部邮件挑出最有用的特征,再划分训练集和测试集 | 筛选放在训练集里做;交叉验证时每一轮重新筛 |
| 特征里含有未来的信息 | 用「用户后来有没有举报这封邮件」当特征 | 只用判断那一刻已经拿得到的信息 |
| 反复看测试集 | 看了测试分数不满意,回去改设置再测 | 测试集只在最后用一次 |
一个简单的警报:分数好得出乎意料,比如小样本上 AUC 0.99,先怀疑数据泄露,而不是模型厉害。
七、第 5 步:训练
通用概念
- 参数:模型自己从数据里学出来的数,比如逻辑回归里每个特征的权重。大模型的参数多达几十亿个,「7B 模型」就是指有 70 亿个参数。
- 超参数:训练前由人定好的设置,比如学多少轮、学习率多大、模型有多复杂。
- 调参:试不同的超参数,选效果最好的一组。必须用验证集或交叉验证来选,不能用测试集。
- 过拟合:见第二节。常见原因是数据太少、模型太复杂。
- 欠拟合:和过拟合相反,模型太简单,连训练数据里的规律都没学到。
- 泛化:模型在没见过的新数据上也能答对的能力。训练的真正目标是泛化好,而不是训练集上的分数高。
- 正则化:在训练中故意限制模型的复杂度,用来防止过拟合。本节后面的 LASSO、数据增强、早停都属于这一类思路。
信号和噪音
信号是特征里确实藏着的、能把两类分开的信息。模型能学的只有这些信息,特征里没有,模型再厉害也学不出来。
- 有信号:用「邮件里有没有『中奖』」判断垃圾邮件。垃圾邮件里有「中奖」的多,正常邮件里少,模型就能学。
- 没有信号:用「邮件是星期几收到的」判断垃圾邮件。如果两类邮件每天都差不多,不管用逻辑回归还是深度学习,都只能瞎猜,AUC 在 0.5 左右。
- 打个比方:看一个人的身高猜性别,能猜对不少,因为男性平均更高,这里有信号;看生日猜性别,怎么猜都是一半对一半错,没有信号。
噪音是碰巧出现、换一批数据就不成立的东西,比如训练集里垃圾邮件碰巧都在周一发。模型分不清哪个是信号、哪个是噪音,数据越少越分不清。过拟合就是把噪音当成了信号。
可能没有信号的原因:
- 特征选错了:真正有用的信息没被算进特征里,就像拿生日猜性别;
- 标签不准:答案本身错得多,真实的规律被错误答案淹没了;
- 样本太少:即使有信号,也和噪音分不开;
- 问题本身在这个时间点判断不了:当时能拿到的信息里,根本不包含答案。
有没有信号,事先不知道,只能用数据检验。最便宜的办法是先看两类的特征分布有没有错开,再训练一个基线模型,看 AUC 的置信区间下限是否明显高于 0.5。两者都看不出差别,就不值得再上复杂模型。
传统机器学习
传统机器学习指深度学习之前的方法,通常需要人工设计特征,计算量小,数据少时往往比深度学习更好用。常用工具是 Python 的 scikit-learn。各算法适合什么场景,见第十一节。
- 线性回归:做回归任务。给每个特征一个权重,加权求和得到预测值,比如「面积每多 1 平方米,房价多 5 万元」。
- 逻辑回归:做分类任务。给每个特征一个权重,加权求和后换算成 0 到 1 之间的概率。比如有「中奖」字样加分、发件人是同事减分,总分越高越可能是垃圾邮件。它虽然叫「回归」,却是分类模型:中间那一步像线性回归一样算出一个连续的总分,名字是按这一步起的;但它最后交出的是类别,所以是分类。判断一个模型做什么任务,看它最后交出什么。
- 决策树:由一串是否题组成的判断流程,比如「发件人陌生吗?是的话再问:有链接吗?……」。
- 随机森林:训练几百棵决策树,每棵树只看随机抽出的一部分样本和特征,所以各不相同,最后由所有树投票。
- 梯度提升树:一棵接一棵地训练决策树,后一棵专门纠正前面的错误。XGBoost、LightGBM 是常用的实现,表格数据上效果通常最好。
- 特征筛选:从很多特征里挑出少数最有用的几个。特征多、样本少时必须做。
- LASSO:一种加了惩罚的逻辑回归(做回归任务时是线性回归),也是最常用的特征筛选方法。它会把作用不大的特征的权重压成零,相当于自动删掉它们。几个特征很像时,它往往只留一个,选哪个带点随机。
- Ridge(岭回归):和 LASSO 一样在训练时加惩罚,但只把权重压小,不压成零,所以不删特征。相关的特征会一起留下、分摊权重,结果更稳定,只是不好说清模型靠哪几个特征判断。打比方:LASSO 是裁员,Ridge 是全员降薪。
- 弹性网络:LASSO 和 Ridge 的折中,既能删掉一部分特征,又能让相关的特征一起留下。
- 每特征 10 事件:一条经验规则,这里的「事件」指少数类的样本。模型里每放一个特征,少数类大约要有 10 个样本。比如只有 50 封垃圾邮件,逻辑回归最多放 5 个特征。
深度学习
深度学习的常用工具是 PyTorch。网络结构有哪些可选、各适合什么场景,见第十一节。
- 神经网络:由很多层简单计算单元连起来的模型。「深度」指层数多。
- CNN(卷积神经网络):擅长处理图像的网络,靠在图像上滑动的小窗口提取局部图案。
- Transformer:目前最主流的网络结构,最早用于文本,大语言模型都基于它,现在也广泛用于图像。
- 损失:衡量模型的猜测和标签差多少的一个数。比如一封垃圾邮件,模型只说「10% 可能是垃圾邮件」,损失就大;说「95%」,损失就小。训练就是不断调参数,让损失变小。
- 梯度下降:调参数的基本方法。每次都朝着「让损失下降最快」的方向把参数挪一小步。
- 学习率:每一步挪多大。太大会来回跳、学不稳;太小学得太慢。它是最重要的超参数之一。
- 批:每次一起交给模型的一小组样本,比如 32 封邮件。模型看完一批就调整一次参数。
- 轮:所有训练样本都看完一遍叫一轮,通常要训练几十到几百轮。
- 预训练:先用大量通用数据把模型练出基本功。比如先用网上的海量文本,让模型学会理解语言。
- 微调:在预训练好的模型上,用自己的少量数据再练,学会具体任务。比如再用一万封标好的邮件,让它学会识别垃圾邮件。预训练加微调需要的数据比从零开始学少得多。
- 迁移学习:把在一个任务上学到的能力用到另一个任务上,预训练加微调就是最常见的做法。
- 数据增强:把样本稍作改变当成新样本,比如把图像轻微旋转、翻转。这样能让模型不要死记某个样本。
- 类别加权:认错少数类时,损失算得更重。比如正常邮件和垃圾邮件是 19 比 1,就把漏掉一封垃圾邮件的损失乘以 19,防止模型全判成正常邮件。代价是模型给出的概率会整体偏向少数类,不再准确。如果只看排序,或者能另定阈值,就不必加权。
- 早停:验证集上的分数不再提高时就停止训练,防止过拟合。
- 集成:训练几个模型,最后取平均或投票,结果更稳定。
- GPU:显卡。深度学习的计算量很大,一般要用 NVIDIA 显卡;传统机器学习用普通电脑就够了。
八、第 6 步:评估
下面的指标都在模型没见过的样本上计算。固定划分时用测试集;用交叉验证时,每一轮在当考题的那一份上计算,再把 5 轮的结果合起来,见第六节。
分类任务
模型对每个样本输出一个概率,比如「这封邮件 72% 可能是垃圾邮件」。分类指标按它们回答的问题分成三组。
第一组:定一个阈值,看判得对不对。
阈值是把概率变成判断的分界线。比如阈值定 0.5,高于 0.5 就判为垃圾邮件。阈值要在训练阶段定好,测试时不能改。
混淆矩阵是把模型的判断和标签对照,排成的四格表。本组的指标都从这张表算出来。
| 实际是垃圾邮件 | 实际是正常邮件 | |
|---|---|---|
| 模型判为垃圾邮件 | 拦对了 | 误拦 |
| 模型判为正常邮件 | 漏掉了 | 放行对了 |
- 准确率:判对的占全部的比例,也就是「拦对了」加「放行对了」,除以全部邮件。两类数量相差大时会骗人:一万封里有五百封垃圾邮件,模型全判「正常」,准确率也有 95%,却一封垃圾邮件都没找出来。
- 召回率(敏感度):阳性里被找出来的比例。垃圾邮件里有多少被拦下了。医学上习惯叫敏感度。
- 精确率(阳性预测值):模型判为阳性的样本中,真是阳性的比例。被拦下的邮件里有多少确实是垃圾邮件。医学上习惯叫阳性预测值。
- 特异度:阴性里被正确认出的比例。正常邮件里有多少没被误拦。
- F1 分数:召回率和精确率的综合。两者都高时它才高,只要有一个低,F1 就低。
第二组:不定阈值,看模型能不能把两类分开。
- ROC 曲线:把阈值从高调到低,召回率会升高,误判率也会升高。误判率指正常邮件被误拦的比例,等于 1 减特异度。把每个阈值下的召回率和误判率画成一条曲线,就是 ROC 曲线。
- AUC:ROC 曲线下的面积,通常在 0.5 到 1 之间,低于 0.5 说明模型把两类弄反了。直观含义是:随机抽一封垃圾邮件和一封正常邮件,模型给垃圾邮件打的概率更高的机会有多大。它和阈值无关,适合比较不同模型。
第三组:看模型给的概率准不准。
- 校准度:模型给的概率是否名副其实。模型说「70% 可能是垃圾邮件」的那些邮件里,实际应当约有 70% 是垃圾邮件。
回归任务
- 平均绝对误差(MAE):预测值和真实值平均差多少。比如房价预测平均差 20 万元。
- 均方根误差(RMSE):和平均绝对误差类似,但对差得特别多的样本罚得更重。
- R²:衡量预测比「一律猜平均值」好多少。比如房价预测,一律猜所有房子的平均价是最笨的办法。R² 是 1 表示完全猜对,是 0 表示和一律猜平均价一样,小于 0 表示还不如它。
分割和检测任务
- Dice 系数:模型圈出的区域和标准答案重叠的程度,算法是重叠部分的 2 倍除以两块区域面积之和。0 是完全不重叠,1 是完全重合。医学分割最常用。
- IoU(交并比):和 Dice 类似,是重叠部分除以两者合起来的面积,检测任务常用。
通用
- 置信区间:分数的可能波动范围。样本少时同一个模型换一批数据测,分数会上下波动。比如垃圾邮件和正常邮件各 30 封时,测出 AUC 0.8,95% 置信区间约是 0.69 到 0.91,真实水平可能在这个范围里的任何位置。
- Bootstrap:计算置信区间的常用方法。从现有样本里有放回地随机抽出同样多的样本,算一次分数,重复 1000 次,去掉最高和最低各 2.5%,剩下的范围就是 95% 置信区间。同一个人有多条记录时,要按人抽,抽中一个人就带上他的全部记录,否则区间偏窄。
- 可解释性:能不能看出模型凭什么做判断。传统模型看特征权重;深度学习常用热力图,也就是把模型最关注的区域在图像上标成红色的图。
- 学习曲线:模型效果随训练样本量增加而变化的曲线,可以用来估计再加数据还有没有用。
- 外部验证:用另一个来源的数据再测一次,模型和阈值都不改,比如换一家医院、换一个地区的用户。
九、上线以后
- 推理:用训练好的模型对新数据做预测。训练是「学」,推理是「用」,推理的计算量小得多。
- 部署:把模型装到实际系统里供人使用。
- 数据漂移:上线后的数据和训练数据慢慢变得不一样,比如垃圾邮件换了新套路,模型效果随之下降。所以模型要定期用新数据检查,必要时重新训练。
十、容易混淆的几对
| 这一对 | 区别 |
|---|---|
| 特征和标签 | 特征是题目,标签是答案。实际使用时只有特征,要预测的正是标签 |
| 分类和回归 | 分类输出类别,回归输出数值。逻辑回归名字带「回归」,其实是分类模型 |
| 参数和超参数 | 参数是模型自己学的,超参数是人事先定的 |
| 验证集和测试集 | 验证集在训练中反复使用,测试集只在最后用一次 |
| 过拟合和欠拟合 | 过拟合是学过头了,死记训练数据;欠拟合是没学会 |
| 过拟合和数据泄露 | 过拟合是模型死记了训练数据,训练集分数好看,测试集一测就露馅;数据泄露是测试的信息漏进了训练,连测试集分数都好看,所以更难发现 |
| 召回率和精确率 | 召回率看阳性找出了多少,精确率看找出来的准不准,两者此消彼长 |
| 准确率和 AUC | 准确率依赖阈值,两类数量相差大时会骗人;AUC 不依赖阈值 |
| 预训练和微调 | 预训练学通用的基本功,微调学具体任务 |
| 训练和推理 | 训练是学,推理是用 |
十一、怎么选算法
第七节列了很多算法,本节说明它们各自适合什么场景。选算法主要看三件事:
- 数据是什么样的:表格数据,比如每封邮件一行、每个特征一列,通常用传统机器学习;图像、文字这类原始数据,通常用深度学习。
- 数据有多少:数据越少,越要选要学的数少的算法,否则容易过拟合。
- 要不要解释:需要向人说清「凭什么这样判断」时,优先选能直接读出理由的算法。
通用的顺序是:先用最简单的算法回答「数据里有没有信号」,有信号再换复杂的,复杂的明显更好才采用。
表格数据:传统机器学习
先补几个第七节没讲过的算法:
- 单一阈值规则:不用学,由人定一条分界线,比如「含有 3 个以上链接就判为垃圾邮件」。
- 支持向量机(SVM):在两类样本之间找一条离两边都尽量远的分界线。
- K 近邻:找出和新样本最像的几个样本,看它们大多属于哪一类。
- 朴素贝叶斯:假设各个特征互不相关,按每个特征分别算出概率,再乘起来。
| 算法 | 适合的场景 | 例子 | 主要短板 |
|---|---|---|---|
| 单一阈值规则 | 已有公认的经验标准,只需要一个参照 | 体检中「空腹血糖 7.0 以上提示糖尿病」这类标准 | 只能用一两个特征,不会学 |
| 逻辑回归 | 样本少、特征少,需要解释,需要可信的概率 | 用年龄、肿瘤大小等几个指标估计术后复发风险,临床预测模型最常用它 | 只能表达「越大越怎样」这类简单关系 |
| LASSO、Ridge、弹性网络 | 候选特征多、样本少,需要自动筛选或防过拟合 | 影像组学从病灶里算出几百个特征,只有一两百个病人 | 仍是逻辑回归,表达不了复杂关系 |
| 决策树 | 想要一张能画出来的判断流程图,数据多且规律清楚 | 客服工单分派:是不是老客户?金额超过 1000 元吗? | 很不稳定,换几个样本,树的样子就全变了 |
| 随机森林 | 几百到几千个样本,特征之间有组合关系,不太需要解释 | 信用卡盗刷:「深夜」和「境外」单独看都正常,同时出现才可疑 | 样本少时容易过拟合;给出的概率常常需要再校准 |
| 梯度提升树 | 几千个以上样本,追求最高的准确度 | 电商预测用户会不会点广告;数据竞赛里的表格题 | 要调的超参数多,样本少时很难调好 |
| 支持向量机 | 样本少、特征多,只要分得开 | 早年的文本分类,比如新闻分栏目;影像组学论文里也常见 | 不直接给概率,要额外换算;不好解释 |
| K 近邻 | 「像不像」容易定义,数据量适中 | 推荐系统:和你口味相近的人还买了什么 | 样本少时「最像的几个」本身就不可靠;特征必须先标准化 |
| 朴素贝叶斯 | 特征极多且大致互不相关,要求算得快 | 早期的垃圾邮件过滤:按每个词在垃圾邮件里出现的概率相乘 | 特征相关时,给出的概率不准 |
图像数据:深度学习
深度学习指用多层神经网络从原始数据里学规律的一大类方法,卷积神经网络只是其中一种网络结构。选深度学习方案,要分别回答三个问题。
网络结构选什么
ImageNet 是一个有上千万张普通照片的公开数据集,很多网络先在它上面训练过,再拿来做别的任务。
| 结构 | 是什么 | 适合的场景 | 例子 |
|---|---|---|---|
| 三维卷积神经网络 | 小窗口在三维影像里滑动,提取局部图案,比如 ResNet、DenseNet 的三维版本 | 三维薄层的 CT、MRI;它先天假设相邻像素有关联,需要的数据相对少 | 用胸部 CT 判断肺结节是良性还是恶性 |
| 二维卷积神经网络 | 一张一张地看平面图像 | 普通照片、X 光片;能直接用在 ImageNet 上训练过的网络 | 用皮肤照片区分痣和黑色素瘤;用胸片判断肺炎 |
| 2.5D 卷积神经网络 | 把相邻几层叠在一起,当成一张多通道的平面图像来看 | 层厚 5 毫米以上的厚层扫描,上下方向信息不全 | 层厚较大的常规 CT 上判断有没有出血 |
| Transformer | 把图像切成小块,让每一块和其他所有块比较,比如 ViT、Swin Transformer | 数据量很大,或者有大规模预训练;擅长看全局关系 | 在海量图像上预训练的通用视觉模型 |
| 卷积加 Transformer 的混合结构 | 卷积提取局部图案,Transformer 看整体关系 | 数据较多,既要细节又要整体 | Swin UNETR 用于器官和肿瘤分割 |
Transformer 没有「相邻像素有关联」这个先天假设,要从数据里自己学出来,所以数据少时一般比不过卷积神经网络。
多次检查怎么输入
有些任务要比较同一个对象前后两次的图像,比如同一个病人两次检查的片子、同一地点两年前后的卫星照片。孪生网络是指两份输入分别交给两个结构和权重完全相同的网络,再比较两边提取出的图案。
| 做法 | 怎么做 | 适合的场景 | 例子 |
|---|---|---|---|
| 叠成多通道 | 两次的影像叠在一起,交给同一个网络 | 两次影像已经对齐,做法最简单 | 把同一个病人前后两次的 CT 对齐后叠在一起,判断病灶有没有变化 |
| 孪生网络 | 两次影像分别过同一个网络,再比较 | 重点是「哪里变了」,或两次影像没有完全对齐 | 卫星图像变化检测:同一地点两年前后的照片,找出新盖的楼;人脸验证:两张照片是不是同一个人 |
怎么用上别人训练好的网络
特征提取器是指把预训练好的网络固定不动,只用它把每张影像变成一串数,再把这串数交给逻辑回归之类的简单算法。
| 做法 | 适合的数据量 | 例子 |
|---|---|---|
| 从零训练 | 几万例以上 | 大型筛查项目,有十几万张已标注的眼底照片 |
| 预训练加微调 | 几百到几千例 | 先在 ImageNet 的上千万张照片上学会看图,再用几百张自己拍的零件照片,学会挑出有缺陷的零件 |
| 只当特征提取器 | 几十例 | 只有几十个病例,连微调都学不动时,只训练最后的逻辑回归 |
医学影像上已有一些公开的预训练网络,比如 MedicalNet、Models Genesis 和 Swin UNETR 的预训练权重,可以省掉自己预训练这一步。能不能用、许可证和输入格式是否合适,使用前要逐个核实。
比较算法时的规矩
- 用同样的数据划分:每种算法用完全相同的训练样本和考题,分数才能直接比。
- 挑算法也是挑设置:试了五种算法、只报最好的那个,分数同样会被运气抬高,道理见第六节「嵌套交叉验证」。要么把选算法放进嵌套交叉验证的内层,要么事先定好只比哪几种,并把每一种的结果都报告出来。
- 明显更好才换:新算法的置信区间要明显高于简单算法。如果两者大面积重叠,就保留更简单、更好解释的那个。
十二、自测题
先遮住后面的参考答案,用自己的话回答,再对照。
- 一个样本由哪两部分组成?用垃圾邮件举例说明。
- 预测明天的气温是分类任务还是回归任务?为什么?
- 为什么要把一部分数据锁起来当测试集?验证集和它有什么区别?
- 同一个用户的多条记录分别放进训练集和测试集,会出什么问题?这叫什么?
- 模型在训练集上准确率 99%,在测试集上 70%,说明什么?有哪些办法改善?
- 一万封邮件里有五百封垃圾邮件,模型全判「正常」,准确率和召回率各是多少?
- 为什么先做基线模型,再做复杂模型?
- 数据很少时,深度学习有哪些办法弥补?至少说出三个。
- 学习率太大或太小,分别会怎样?
- 模型上线半年后效果变差了,可能是什么原因?
参考答案
每题先给一句话标准答案,再补充容易答漏或答错的地方。
1. 样本由哪两部分组成
标准答案:样本由特征和标签组成,特征是题目,标签是事先定好的标准答案。比如一封邮件,特征是有没有「中奖」、发件人是否陌生,标签是「垃圾邮件」或「正常邮件」。
- 标签是标准答案,不是模型的结论。 标签是事先由人定好的,比如用户点了「举报垃圾邮件」。模型给出的叫「预测」,训练就是让模型的预测去贴近标签。
- 只有训练和测试时才有标签。 模型真正投入使用时,手里只有特征,要猜的正是标签。如果新邮件已经知道是不是垃圾邮件,就不需要模型了。
- 特征不一定是人挑出来的属性。 「发件人、中奖关键词」是人工设计的特征,适合传统机器学习。深度学习可以直接把邮件全文当特征,让模型自己找有用的地方。
2. 预测明天的气温是分类还是回归
标准答案:回归任务,因为输出的气温是一个能比大小、算差值的数值,不是类别。
- 任务类型由「要它输出什么」决定,不由题材决定。 同样是天气,预测「明天几度」是回归;预测「明天会不会超过 35 度」或「明天是晴、阴还是雨」就是分类。所以定义任务时,问的是「我要它给出什么答案」。
- 任务类型决定评估指标。 回归看误差有多大,比如平均绝对误差(MAE)是「平均差 2 度」;分类看判对多少,比如召回率、AUC。用错指标会得出错误的结论。
- 输出是数字,不一定是回归。 把「垃圾邮件、正常邮件」记成 1 和 0,它仍然是分类,因为 1 和 0 只是类别的代号。判断标准是这些数字能不能比大小、算差值:30 度比 20 度高 10 度,有意义;类别 1 减类别 0,没有意义。
3. 为什么要锁起测试集,验证集和它有什么区别
标准答案:测试集用来估计模型面对新数据的真实水平,训练和挑设置时都不能碰,否则分数虚高;验证集从训练数据中分出,在训练过程中反复使用,用来挑超参数和决定何时停止。
- 说清「影响」是怎么影响的。 测试集的作用是估计模型面对从没见过的新数据时有多准,也就是泛化能力。模型见过考题,分数就会比真实水平好看,这个估计也就不成立了。
- 验证集的用途要说出来。 一是挑超参数,比如学习率多大、LASSO 罚多重;二是决定何时停止训练,也就是早停。
- 测试集只能用一次。 「训练时不给模型看」还不够。如果看了测试集的分数觉得不好,回去改设置再测,反复几次,就等于拿测试集挑设置,它就悄悄变成了验证集,分数同样会虚高。所以测试集要在一切都定下来以后只测一次。
- 打个比方:验证集是模拟考,可以考很多次,考完根据成绩调整复习方法;测试集是期末考试,只考一次,成绩就是最终水平。
4. 同一用户的记录分在训练集和测试集两边
标准答案:模型会认出这个用户,而不是真正学会判断,测试分数虚高。这叫数据泄露,解决办法是按用户分组划分。
为什么是数据泄露。 同一个用户的记录很像,比如写邮件的习惯、常用词都差不多。模型在训练集里见过这个用户,测试时其实是认出了这个人,而不是学会了判断。测试分数好看,但换一批新用户就不准了。
容易错答成过拟合。 两者都让分数好看,但问题出在不同地方:
过拟合 数据泄露 问题出在哪 模型:学过头了,把巧合当规律 数据划分:测试的信息漏进了训练 典型表现 训练集分数高,测试集分数低 训练集、测试集分数都高,上线后才露馅 打比方 学生死记练习题答案,考试换了题就不会 学生提前偷看了考题 数据泄露更危险。 过拟合在测试集上就能被发现;数据泄露发现不了,因为测试集本身已经被污染了。
怎么避免:按组划分。同一个用户的所有记录,要么全放进训练集,要么全放进测试集。
5. 训练集 99%、测试集 70%
标准答案:训练集和测试集分数差距大,说明过拟合。改善办法有增加样本、数据增强、减少特征、换简单模型或加惩罚、早停、集成。
判断依据是差距大。 模型在见过的题上很好,换了新题就不行,说明死记了训练数据。如果两个都低,比如都是 70%,而且离预期差得远,可能是欠拟合,模型太简单、没学会;也可能是数据本身只能做到这个程度,比如标签不准或者信号太弱,见第七节「信号和噪音」。
办法按「问题出在哪」来记。 防止过拟合的思路统称正则化,就是限制模型别学过头:
问题 办法 数据太少 增加样本(最根本);数据增强,把图像轻微旋转、翻转当成新样本 特征太多 特征筛选,比如 LASSO 模型太复杂 换简单的模型,比如从深度学习退回逻辑回归;加惩罚,比如 LASSO、Ridge;限制决策树的层数 训练太久 早停,验证集分数不再提高就停 结果不稳 集成,训练几个模型取平均 LASSO 不只是减少特征的工具。 它本身就是一种加惩罚的逻辑回归,所以同时属于「特征筛选」和「加惩罚」两类。Ridge 不减特征,但同样能防过拟合。
还要排除另一种可能。 训练集和测试集的数据本身差别很大,比如训练集都是去年的邮件,测试集是今年的、垃圾邮件换了新套路。这时差距不完全是过拟合造成的。
6. 模型全判「正常」的准确率和召回率
标准答案:准确率 95%,召回率 0%。说明两类数量相差大时,准确率会骗人。
写出算法,不只给数字。 准确率 = 判对的 ÷ 全部 = 9500 ÷ 10000 = 95%,因为 9500 封正常邮件都「放行对了」;召回率 = 拦下的垃圾邮件 ÷ 全部垃圾邮件 = 0 ÷ 500 = 0%。
准确率为什么会骗人。 模型什么都没学会,只是一律猜多数类,准确率就有 95%。看上去很高,其实一封垃圾邮件都没找出来,这个模型毫无用处。这就是类别不平衡带来的问题。
其他指标能不能发现问题:
- 特异度 = 100%:正常邮件一封都没误拦,也会骗人;
- 精确率算不出来:模型一封都没判为垃圾邮件,分母是 0;
- AUC:如果模型是给所有邮件打了同样的低分,AUC = 0.5,等于瞎猜,一下就看出问题。AUC 不看阈值、只看排序,也不受类别比例影响。如果模型其实能把垃圾邮件排在前面、只是阈值定得太高,AUC 会明显高于 0.5,这时该调的是阈值,不是模型。
所以类别不平衡时,要看召回率、AUC 这类指标,不能只看准确率。
怎么让模型不偷懒:有两种办法。一是另定阈值:只要模型能把垃圾邮件排在前面,把阈值从 0.5 调低就能找出来。二是训练时用类别加权,漏掉一封垃圾邮件的损失乘以 19(9500 ÷ 500),代价是概率不再准确。只关心排序、能另定阈值时,优先用第一种。
7. 为什么先做基线模型
标准答案:基线模型简单、训练快,先用它回答「数据里有没有可学的信号」,同时给复杂模型当参照,复杂模型比不过它就没有意义。
- 先回答有没有信号。 这是最重要的理由。如果连简单模型都只有 AUC 0.5 左右,通常不是模型不够复杂,而是数据或标签有问题,比如标签不准、特征里根本没有区分两类的信息。这时应该回第 2 步补数据、修标签,而不是换更复杂的模型。
- 帮你查出流程里的错误。 基线模型简单,结果好坏都容易看懂。如果它的分数高得离谱,比如 AUC 0.99,多半是数据泄露,而不是模型厉害。先在简单模型上把数据划分、评估流程跑通、查干净,再上复杂模型。
- 好解释。 逻辑回归每个特征的权重都能看懂,比如「链接越多,越可能是垃圾邮件」,业务人员容易接受。
- 数据少时,基线模型可能就是最终模型。 复杂模型需要的数据多得多,数据少时往往比不过简单模型。
- 基线模型的特征是人选的吗? 通常是,但不是必须。基线的意思是「简单」,不是「特征由人选」:
- 特征怎么来:基线一般用传统机器学习,特征是人设计好计算规则、由程序算出来的,比如「有没有『中奖』」「链接几个」,影像里的体积、纹理。深度学习则直接看原始数据,自己找特征。
- 特征怎么挑:可以人凭经验直接挑,也可以从一大堆候选特征里用 LASSO 自动挑。
- 最简单的基线连特征都不用:比如一律猜多数类,或者「含『中奖』就判垃圾」这样一条规则。任何模型至少要比它们强。
8. 数据很少时,深度学习怎么弥补
标准答案:预训练加微调(最重要)、数据增强、早停、集成,以及用更小的网络或微调时固定前几层。
- 容易错答成交叉验证。 交叉验证解决的是评估问题,不是训练问题:数据少时,它让每个样本都轮流当一次考题,分数估得更准,但不会让模型本身学得更好。就像多考几次能更准地知道学生的水平,却不会让学生变聪明。
- 预训练加微调为什么最重要。 先用大量公开数据让模型学会基本功,再用少量自己的数据学具体任务。打个比方:先让一个人读过大量文章、学会了中文,再教他分辨垃圾邮件,比教一个不识字的人快得多。
- 让模型少学点东西。 用更小的网络;或者微调时把预训练好的前几层固定不动,只训练最后一层。要学的数少了,几十个样本才学得动。
- 类别加权不算。 它解决的是两类数量不平衡,不是数据少。但数据少时往往也不平衡,所以常一起用。
- 最实在的办法:不用深度学习。 数据实在太少时退回基线模型。复杂模型比不过简单模型,就保留简单模型。
- 按思路记:
思路 办法 借别人的数据 预训练加微调 把自己的数据变多 数据增强 让模型别学过头 早停、集成、小网络、固定前几层
9. 学习率太大或太小
标准答案:太大会来回跳、学不稳,甚至越学越差;太小学得太慢,规定的轮数用完了还没学好。
- 打个比方。 训练像在大雾里下山找最低点,只能摸着脚下的坡往下走,学习率就是每一步迈多大:
- 步子太大:一步跨过谷底落到对面山坡,再一步又跨回来,来回跳。更糟时越跳越高,损失越来越大,训练直接失败,程序里常见的表现是损失变成 NaN,也就是算不出来的数;
- 步子太小:方向对,但挪得太慢。轮数用完时模型还没学好,看上去像欠拟合;还可能卡在半山腰的小坑里出不来。
- 怎么看出来:看损失曲线,也就是每一轮的损失画成的线。正常是先快速下降、再慢慢变平;太大是上下乱跳或越来越高;太小是下降得非常慢,几乎是一条缓缓倾斜的直线。
- 怎么定:学习率是超参数,靠试,用验证集来选。
- 试几个相差十倍的值,比如 0.01、0.001、0.0001,看哪个的损失曲线最好;
- 先大后小:开始步子大,快速走到谷底附近,后面逐渐减小,精细找最低点。这种安排叫学习率调度。
- 微调时学习率要小。 预训练好的模型已经学会了基本功,步子太大会把学到的东西冲掉,所以微调的学习率通常比从零训练小很多。
10. 上线半年后效果变差
标准答案:最常见的原因是数据漂移,也就是上线后的数据和训练数据慢慢变得不一样了。要用新数据重新评估,必要时重新训练。
- 漂移分两种,知道是哪种才好处理:
- 输入变了:数据本身的样子变了。比如垃圾邮件换了新套路,不写「中奖」改写「福利」;医院换了新的检查设备,片子的亮度、清晰度不一样了;
- 规律变了:同样的输入,正确答案变了。比如以前「含链接的营销邮件」算垃圾,后来用户订阅了,就算正常邮件;邮件平台调整了垃圾邮件的认定标准,原来算正常的推广邮件现在算垃圾。
- 先排除不是漂移的原因,再决定重新训练:
- 流程出错了:上游系统改了,比如邮件系统换了编码格式,预处理把正文读成了乱码。模型没问题,修好流程就行;
- 用的人群变了:比如从一家医院推广到别的医院,病人构成不同。这其实是外部验证没做够;
- 模型从一开始就没那么好:评估时有数据泄露或过拟合,分数虚高,上线后才露馅。重新训练解决不了,要回头查评估流程。
- 怎么及早发现:不要等用户抱怨。上线后定期抽一批新数据请人标注,算一遍 AUC 等指标;同时监控输入,比如图像亮度分布、检查参数,和训练数据比有没有明显变化。
- 重新训练也要按原来的规矩来:新旧数据合在一起,照样按组划分、锁好测试集,重新评估后再替换旧模型。