Skip to content

传统机器学习与评测

目录

1. 学习目标

  • 理解线性/逻辑回归、决策树、Bagging、随机森林和 Boosting 的核心机制与归纳偏置;
  • 能够从偏差—方差、数据规模、特征类型、可解释性和推理成本选择基线模型;
  • 能够推导逻辑回归概率、交叉熵和梯度,解释决策树分裂及集成学习为何有效;
  • 能够从混淆矩阵推导 Accuracy、Precision、Recall、F1,并根据业务代价选择阈值;
  • 能够实现一个训练集拟合预处理、验证集选阈值、测试集终评的最小分类流水线;
  • 能够排查类别不平衡、过拟合、泄漏、概率失准、训练/服务偏差和分布漂移。

2. 面试结论

2.1 30 秒回答

传统机器学习不是“过时的小模型”,而是一组归纳偏置明确、数据效率高、易解释且部署成本低的方法。逻辑回归学习线性决策边界和概率,决策树用特征阈值递归划分空间,Bagging 通过并行模型平均降方差,Boosting 通过串行修正残差降偏差。模型优劣不能只看 Accuracy:要从业务误判代价出发看混淆矩阵、Precision、Recall、F1、排序能力、概率校准和阈值,并保证所有预处理与重采样只在训练数据中拟合。

2.2 一分钟复述版

我会先建立可解释基线,再按错误结构升级模型。逻辑回归适合近似线性、稀疏高维并需要概率与系数解释的任务;单棵树能表达非线性和交互,但深树方差高;随机森林对多棵去相关树做平均,主要降方差;梯度提升逐轮拟合当前损失的负梯度,通常有更强表格建模能力,但对超参数和数据泄漏更敏感。评测时先固定数据边界,在训练集内完成缺失处理、编码、标准化、采样和模型拟合;验证集选择超参数与阈值;测试集只评冻结方案。类别不平衡时 Accuracy 可能掩盖少数类失败,应报告 Precision/Recall、PR 曲线、校准和业务成本,并按时间、来源、用户群做切片与错误分析。

3. 面试官为什么问

  • 核心考察点:是否能把算法假设、优化目标、评测指标和业务决策连成一条链;
  • 对应岗位与级别:初级岗位看算法与指标定义,中高级岗位看阈值、校准、泄漏、长尾、线上监控和复盘;
  • 优秀回答的区分度:会先给简单基线与验证方法,再根据残差和约束选择树或集成,不用“某模型更先进”代替证据;
  • 项目追问信号:如果只报 Accuracy/AUC、不说正类定义、阈值、数据窗口和错误代价,评测结论通常不可复核。

4. 概念与边界

小白先这样理解:医院筛查不能只看“猜对多少人”

某种病一万人中只有十人。若筛查系统把所有人都判为健康,Accuracy 仍接近 99.9%,但一个病人也没找出来。把真实患病当作正类:Recall 是十位患者中成功筛出几位,Precision 是所有被叫去复查的人中真正患病的比例;调低判阳性阈值通常能少漏诊,却会增加误报和复查压力。这里患者真实状态与筛查结果的四种组合,就是混淆矩阵,模型选择本质上要结合漏诊和误报的不同代价。

类比边界: 指标只能量化预测表现,不能替医生决定诊疗、伦理或资源分配;真实任务还受患病率变化、概率校准、数据偏差和分群差异影响。AUC 等排序指标也不能替代某个实际阈值下的业务验证。

4.1 什么是传统机器学习

本文所称传统机器学习主要指不以大规模多层神经网络端到端学习为核心的监督学习方法,包括线性模型、核方法、树模型和集成学习。这个划分是工程习惯而非严格数学边界。

方法主要归纳偏置优势主要限制
线性回归输出是特征线性组合快、可解释、易诊断难表示强非线性与交互
逻辑回归对数几率是特征线性组合概率输出、适合稀疏特征原始空间决策边界线性
决策树轴对齐阈值递归划分非线性、可处理交互、少量预处理深树高方差、不稳定
随机森林Bootstrap + 随机特征使树去相关稳健、并行、较少调参模型较大、概率可能需校准
梯度提升树串行加法模型修正当前损失表格数据上表达力强对参数、噪声和泄漏敏感

传统模型和深度学习不是按效果绝对排序。样本较少、特征已有业务语义、表格结构强且解释/延迟受限时,传统模型经常是合理首选;图像、音频、视频和长文本的原始高维表示通常更依赖深度表示学习,但也可把预训练 Embedding 交给传统分类器。

4.2 分类、回归、排序与概率估计

  • 分类:输出离散类别或类别概率;
  • 回归:输出连续值,如时长、价格或风险损失;
  • 排序:关注候选相对次序,目标与分类概率不完全相同;
  • 概率估计:要求输出概率与真实频率一致,排序能力好不自动等于概率校准好;
  • 决策:把概率与误判成本、容量和规则结合后输出行动,阈值属于决策层而非模型固有真理。

4.3 参数、超参数与特征

  • 参数:由训练数据直接拟合,例如逻辑回归权重、树的分裂节点;
  • 超参数:在外层选择,例如正则强度、树深、树数量、学习率;
  • 特征:预测时真实可获得的信息表达;
  • 标签:希望预测的目标,必须明确生成过程、延迟和噪声;
  • 阈值:把概率转为类别或动作的规则,应在验证集按业务目标选择。

模型不会自动修正错误的标签定义或不可用特征。高质量特征工程的本质是用预测时可获得的信息表达业务因果与结构,而不是在全量数据上制造泄漏。

5. 原理剖析

5.1 逻辑回归:从线性得分到概率

给定 xRd、权重 wRd 和偏置 bR,先计算线性得分:

z=wTx+b

再用 Sigmoid 映射到正类概率:

p(y=1x)=σ(z)=11+ez

对数几率为:

logp1p=wTx+b

因此逻辑回归假设“正类对数几率”对输入线性,而不是假设概率本身线性。二元交叉熵目标为:

J(w,b)=1ni=1n[yilogpi+(1yi)log(1pi)]

其中,n 是训练样本数,yi{0,1}pi 是第 i 个样本的正类概率。其梯度可写为:

wJ=1nXT(py),Jb=1ni(piyi)

若加入 L2 正则 λw22/2,权重梯度再加 λwλ0 控制收缩强度;是否对偏置正则化需明确实现约定。

5.2 决策树:用局部划分降低不纯度

分类树在候选特征与阈值中选择让子节点更“纯”的划分。节点中第 k 类比例为 pk 时,Gini 不纯度为:

Gini=1k=1Kpk2

其中,K 是类别数。候选划分的加权不纯度为:

Gsplit=nLnGL+nRnGR

nL,nR 是左右子节点样本数,GL,GR 是各自不纯度。算法选择使父节点不纯度减去 Gsplit 最大的划分,并递归执行。

单棵深树能把训练样本切得很细,偏差低但方差高;限制 max_depth、叶节点最小样本数、剪枝或正则化可以控制复杂度。连续特征的精确分裂若预排序,典型训练成本与实现相关,常见分析近似为每层 O(nd) 或整体 O(ndlogn);预测成本约为树深 O(h)。不要把某个复杂度当作所有树实现的固定结论。

5.3 Bagging 与随机森林为何降低方差

Bagging 对训练数据做 Bootstrap 采样,独立训练多个高方差基学习器,再平均回归输出或投票分类。若每个模型方差为 σ2,模型两两相关系数近似为 ρM 个模型平均的方差近似:

ρσ2+1ρMσ2

其中,M 是模型数。增大 M 只能消除不相关部分,相关性 ρ 高时收益受限。随机森林在每个节点只考察随机特征子集,主动降低树之间相关性;代价是单棵树可能更弱。

5.4 Boosting 为何降低偏差

Boosting 构建加法模型:

Fm(x)=Fm1(x)+ηhm(x)

其中,hm 是第 m 轮弱学习器,η 是收缩学习率。梯度提升让 hm 近似拟合当前损失对模型输出的负梯度,因此每轮针对当前错误方向改进。

Bagging 的模型大体并行、重点降方差;Boosting 串行依赖、重点逐步降低偏差。Boosting 也会过拟合噪声,需通过树深、学习率、轮数、子采样和验证集早停控制。

5.5 从混淆矩阵到业务指标

二分类定义:

  • TP:真实正类且预测正类;
  • FP:真实负类但预测正类;
  • TN:真实负类且预测负类;
  • FN:真实正类但预测负类。

常用指标:

Accuracy=TP+TNTP+FP+TN+FNPrecision=TPTP+FP,Recall=TPTP+FNF1=2PrecisionRecallPrecision+Recall

Precision 关心“报出来的正类有多少是真的”,Recall 关心“真实正类找回多少”。F1 是两者调和平均,但不使用 TN,也没有显式表达业务成本。若假阴性代价远高于假阳性,可使用 Fβ、成本矩阵或在满足 Precision 下限的条件下最大化 Recall。

5.6 ROC-AUC、PR-AUC、阈值与校准

  • ROC 曲线:不同阈值下 TPR 对 FPR;ROC-AUC 衡量随机正样本得分高于随机负样本的概率意义,主要反映排序;
  • PR 曲线:不同阈值下 Precision 对 Recall;正类稀少时通常更直接展示少数类检出与误报权衡;
  • 阈值:由业务代价、人工容量和目标约束决定,不能固定认为 0.5 最优;
  • 校准:预测为 0.8 的样本群应有接近 80% 的正类频率;AUC 高的模型仍可能过度自信或欠自信;
  • Log Loss/Brier Score:评价概率质量,和只看最终类别不同。

若只报告一条 AUC,面试官无法知道选择了什么正类、数据先验、实际阈值、误报成本以及概率是否可用。

5.7 完整训练与评测闭环

图 1:传统分类模型的训练、选择与上线闭环(替代文本:训练集内部拟合清洗、编码、标准化、重采样和候选模型,验证集选择超参数、校准与阈值,冻结后在测试集按总体和业务切片评估,再发布并监控漂移与错误样本。)

图表加载中…

读图结论: 模型训练只是中间节点;预处理边界、阈值选择、切片评测和线上反馈共同决定方案是否可信。

5.8 类别不平衡的处理因果链

  1. 先确认少数类是否真是业务重点,以及标签是否可靠;
  2. 使用分层或业务边界切分,确保验证/测试集保留真实先验;
  3. 只在训练集使用过采样、欠采样、类别权重或困难样本挖掘;
  4. 根据业务约束选择 PR、Recall、Precision、成本和校准指标;
  5. 在验证集选择阈值,不更改测试集先验迎合指标;
  6. 上线后监控先验变化,因为先验变化会改变 Precision 和最优阈值。

6. 实现与代码

6.1 最小可运行示例:逻辑回归、验证选阈值与测试终评

运行环境:Python 3.10+,仅使用标准库。样本是明确标注的合成数据,用于验证流水线与公式,不代表真实业务指标。

python
import math
import random


def sigmoid(z):
    # 分支写法避免 exp(-z) 在 z 很小时溢出。
    if z >= 0:
        return 1.0 / (1.0 + math.exp(-z))
    exp_z = math.exp(z)
    return exp_z / (1.0 + exp_z)


def fit_scaler(rows):
    means = [sum(row["x"][j] for row in rows) / len(rows) for j in range(2)]
    variances = [
        sum((row["x"][j] - means[j]) ** 2 for row in rows) / len(rows)
        for j in range(2)
    ]
    scales = [math.sqrt(value) if value > 0 else 1.0 for value in variances]
    return means, scales


def transform(rows, means, scales):
    return [
        {
            "id": row["id"],
            "x": [(row["x"][j] - means[j]) / scales[j] for j in range(2)],
            "y": row["y"],
        }
        for row in rows
    ]


def log_loss(rows, weights, bias):
    total = 0.0
    for row in rows:
        probability = sigmoid(sum(w * x for w, x in zip(weights, row["x"])) + bias)
        probability = min(max(probability, 1e-12), 1.0 - 1e-12)
        total -= row["y"] * math.log(probability) + (1 - row["y"]) * math.log(1 - probability)
    return total / len(rows)


def train(rows, learning_rate=0.1, steps=1200):
    weights, bias = [0.0, 0.0], 0.0
    losses = [log_loss(rows, weights, bias)]
    for _ in range(steps):
        grad_w, grad_b = [0.0, 0.0], 0.0
        for row in rows:
            probability = sigmoid(sum(w * x for w, x in zip(weights, row["x"])) + bias)
            error = probability - row["y"]
            for j in range(2):
                grad_w[j] += error * row["x"][j]
            grad_b += error
        for j in range(2):
            weights[j] -= learning_rate * grad_w[j] / len(rows)
        bias -= learning_rate * grad_b / len(rows)
        losses.append(log_loss(rows, weights, bias))
    return weights, bias, losses


def evaluate(rows, weights, bias, threshold):
    tp = fp = tn = fn = 0
    for row in rows:
        probability = sigmoid(sum(w * x for w, x in zip(weights, row["x"])) + bias)
        prediction = int(probability >= threshold)
        if prediction == 1 and row["y"] == 1:
            tp += 1
        elif prediction == 1:
            fp += 1
        elif row["y"] == 0:
            tn += 1
        else:
            fn += 1
    precision = tp / (tp + fp) if tp + fp else 0.0
    recall = tp / (tp + fn) if tp + fn else 0.0
    f1 = 2 * precision * recall / (precision + recall) if precision + recall else 0.0
    return {"tp": tp, "fp": fp, "tn": tn, "fn": fn,
            "precision": precision, "recall": recall, "f1": f1}


rng = random.Random(7)
rows = []
for index in range(160):
    x1, x2 = rng.uniform(-2, 2), rng.uniform(-2, 2)
    noise = rng.gauss(0, 0.35)
    label = int(1.8 * x1 - 1.1 * x2 + noise > 0)
    rows.append({"id": f"sample-{index:03d}", "x": [x1, x2], "y": label})
rng.shuffle(rows)

raw_train, raw_valid, raw_test = rows[:100], rows[100:130], rows[130:]
means, scales = fit_scaler(raw_train)  # 只能从训练集拟合。
train_rows = transform(raw_train, means, scales)
valid_rows = transform(raw_valid, means, scales)
test_rows = transform(raw_test, means, scales)

weights, bias, losses = train(train_rows)
assert losses[-1] < losses[0]

candidate_thresholds = [0.30, 0.40, 0.50, 0.60, 0.70]
threshold = max(
    candidate_thresholds,
    key=lambda value: (evaluate(valid_rows, weights, bias, value)["f1"], -abs(value - 0.5)),
)
test_metrics = evaluate(test_rows, weights, bias, threshold)  # 只在方案冻结后调用。

assert {row["id"] for row in raw_train}.isdisjoint(row["id"] for row in raw_test)
print("selected_threshold=", threshold)
print("initial_loss=", losses[0], "final_loss=", losses[-1])
print("observed_test_metrics=", test_metrics)

6.2 关键实现说明

  • fit_scaler 只读取训练集,验证/测试复用同一均值和尺度,防止预处理泄漏;
  • Sigmoid 使用分支公式,交叉熵对概率裁剪,避免指数和对数数值溢出;
  • error = probability - label 正是 Sigmoid 与交叉熵组合后对线性得分的导数;
  • 阈值只在验证集候选中选择,测试集只计算冻结方案;
  • 训练复杂度为 O(Tnd),其中 T 是步数、n 是训练样本数、d=2 是特征数;阈值搜索为 O(qnvalid)q 是候选阈值数。

6.3 边界条件与验证

  • 极端不平衡数据可能让某个集合没有正样本,指标分母为 0 时必须明确处理;
  • 真实分类任务还需按业务独立单元切分,代码中的随机切分只服务于合成示例;
  • 生产实现应使用框架的稳定 logsigmoid/log_loss,记录模型、缩放器、阈值和标签映射;
  • 对稀疏高维特征应避免稠密展开,并验证特征索引在训练与服务一致;
  • 不把此示例输出写成项目成果;真实结论需要固定数据与独立评测证据。

6.4 技术清单与证据边界

逻辑回归、树模型、阈值和评测指标是算法与决策机制,不绑定 scikit-learn 或其他框架。本文的 Python 标准库代码用于证明公式和边界,生产实现栈只作为参考,具体依赖版本与效果必须由真实项目锁文件和固定评测集确认。

技术点 ID技术点/环节类型采用方案链路职责版本/证据边界
TP-01预处理、训练与服务一致性机器学习流水线教学采用标准库显式实现;生产参考使用可序列化 Pipeline 打包缩放器、模型和特征顺序约束预处理只在训练集拟合,并让离线与在线复用同一变换文中代码要求 Python 3.10+;Pipeline 框架和版本需由项目依赖确认
TP-02表格分类模型监督学习模型先采用逻辑回归作为可解释基线,再按固定评测比较树集成从特征输出概率,为阈值和人工队列提供排序信号本文只验证合成数据上的逻辑回归机制,不包含真实模型效果
TP-03指标、概率与决策阈值评测与决策组件采用验证集选阈值、测试集冻结终评,并记录混淆矩阵和概率质量把概率转换为与漏审、误拦成本和人工容量一致的业务动作指标公式由正文给出;阈值、成本和校准结论必须来自真实标签与独立评测

6.5 横向对比与选型

技术点 ID候选方案优点缺点/代价适用场景不适用场景选择结论与依据
TP-01手写预处理与训练代码机制透明、依赖少、便于验证公式和泄漏边界容易遗漏类别编码、稀疏矩阵、序列化和参数校验教学、最小复现和自定义算法验证多特征、多模型、需要可靠部署的生产流水线本文采用它讲清机制;生产不能直接复制为完整实现
TP-01scikit-learn Pipeline/ColumnTransformer可把拟合边界、列处理和模型序列化为统一对象仍需自定义特征契约、版本和在线语言适配结构化数据基线、批训练和同语言在线推理超大规模分布式训练或非 Python 低延迟服务无法直接承载时生产参考优先,前提是离在线黄金样本和依赖版本验证通过
TP-02逻辑回归训练快、概率和特征方向较易解释,是强基线线性边界难表达复杂交互,对异常值和尺度较敏感稀疏高维、需要解释和快速基线的分类强非线性交互且特征工程不足时默认先用它证明数据与标签有信号,再决定是否增加复杂度
TP-02随机森林或梯度提升树能学习非线性与特征交互,表格任务通常表现稳健模型更大,概率可能需要校准;解释与外推边界更复杂中小型表格数据、交互明显、CPU 推理极高维稀疏特征、严格线性解释或未见范围外推只有在相同切分、阈值和成本下稳定优于逻辑回归时采用
TP-03固定阈值 0.5 + Accuracy实现简单、容易复现忽略类别先验、成本和人工容量;不平衡时会掩盖失败类别近似平衡且误差代价对称的教学基线正类稀少、漏审/误拦代价不同或容量受限仅作基线,不作为默认生产决策
TP-03验证集成本/容量选阈值 + Precision/Recall/校准能把模型分数映射到业务目标,并显式观察错误类型需要可靠验证集、成本定义和持续漂移监控风险分流、人工审核、告警和排序标签极少或成本无法定义且没有人工复核时本文采用该闭环;阈值必须与模型共同版本化并在测试集冻结终评

6.6 参考实现架构

图:架构|传统机器学习训练、决策与监控组件边界

替代文本: 版本化数据经切分门禁进入特征 Pipeline,训练器生成候选模型,验证与校准组件选择模型和阈值,冻结包包含预处理、模型、标签和阈值;在线特征经过同一契约进入模型服务和决策层,监控按切片把反馈送回评测而不直接污染测试集。

图表加载中…

读图结论: 模型只负责输出分数;预处理一致性、阈值选择、规则和人工容量属于独立组件,必须与模型一起版本化和验证。

架构图强调静态边界:训练 Pipeline 不能读取验证/测试统计量,模型服务不能私自决定业务动作,监控回流也不能覆盖历史评测快照。

6.7 技术调用流程

图:技术调用流程|从训练候选到线上决策的正常与门禁失败分支

替代文本: 训练编排器先请求冻结数据和特征 Pipeline,训练候选模型后由评测器在验证集选模型与阈值;门禁失败时拒绝发布,正常时打包部署;在线请求若特征契约通过则输出概率并由决策层结合规则和容量行动,契约失败则回退或人工处理。

图表加载中…

读图结论: 发布前的异常必须阻断候选模型,在线特征异常必须走明确回退;两者都不能以默认值继续并把接口成功误当成质量成功。

调用流程图展示动态顺序:验证集负责选方案,测试集只做冻结终评;在线模型输出概率,最终动作仍由带业务约束的决策层完成。

7. 实际项目案例

示例项目:AI 视频发布前风险分流。 下述项目用于展示传统机器学习的方案选择和排障,不代表已有代码或真实指标。

7.1 背景、目标与约束

  • 目标:对视频进入生成/发布流程前的风险进行概率排序,将有限人工审核能力优先分配给高风险内容;
  • 输入:预测时可用的文本规则命中、上传元数据、音视频技术质量统计和已冻结的内容 Embedding;
  • 输出:风险概率、建议队列、模型版本和可解释的主要特征;
  • 约束:正类稀少、漏审与误拦成本不同、标签延迟且可能复核修改,内容趋势随时间变化;
  • 边界:模型只做分流建议,最终发布门禁还包括规则、版权/授权校验和人工确认。

7.2 项目调用链

  1. 上传服务产生 video_id 和预测时刻;
  2. 特征服务从允许的事件窗口读取特征,并执行与训练一致的缺失处理和编码;
  3. 模型服务输出概率而非直接把 0.5 当业务动作;
  4. 决策层按验证集确定的阈值、人工容量和硬规则分配队列;
  5. 审核结果进入带版本的标签库,不直接覆盖历史标签快照;
  6. 评测服务按时间、创作者、语言、内容类型和概率区间监控质量与校准;
  7. 漂移或质量门禁触发回退旧模型、调整非模型规则或进入再训练流程。

7.3 方案选择与未采用方案

  • 先用逻辑回归:作为可解释基线,验证数据和标签是否有信号,也便于检查特征方向;
  • 若线性模型在特征交互上欠拟合,再比较限制深度的树和集成模型;
  • 随机森林适合稳健基线与并行训练,Boosting 适合逐步拟合复杂表格关系;
  • 不因为类别不平衡就复制验证/测试正样本,真实先验必须保留;
  • 不直接训练端到端视频网络:若数据和算力证据不足,先复用冻结表示并比较传统分类头,降低迭代成本。

7.4 生产故障:现象、根因、解决与验证

现象根因解决验证
Accuracy 很高但高风险内容大量漏过正类稀少、阈值或指标错配改看 Recall/PR/成本,验证集按漏审代价选阈值固定测试集混淆矩阵和困难正类切片
离线正常、线上概率普遍偏高先验漂移、特征缺失、概率未校准检查特征与先验;用独立校准集校准;必要时回退可靠性图、Brier/Log Loss、分概率桶真实频率
换树模型后测试分数异常跃升泄漏字段、同源样本跨集合、预处理全量拟合删除预测后字段,重建组/时间切分和 Pipeline泄漏审计、同源交集为零、重新隔离测试集
灰度后错误集中在新语言训练覆盖不足、编码默认值吞掉未知类别增加 unknown 处理和分切片门禁,收集复核标签新语言影子流量与人工复核,不用总体均值掩盖
服务概率与离线不一致特征顺序、单位、缺失策略或模型版本不一致特征契约、端到端黄金样本、模型与预处理打包同一输入离线/在线逐字段与概率对比
重训后阈值失效概率尺度或类先验变化模型与阈值共同版本化,重新做验证选择新版本校准、容量和测试成本回归

7.4.1 故障演练:Accuracy 很高但高风险内容大量漏审

  • 现象与影响:总体 Accuracy 维持高位,但少数高风险正类的漏检增加,错误内容绕过人工审核。
  • 定位证据:检查混淆矩阵、正类 Recall、PR 曲线、阈值版本和困难正类切片,不用总体均值掩盖少数类。
  • 根因:类别极不平衡,训练和发布只优化 Accuracy;阈值没有纳入人工容量与漏审成本。
  • 临时止损:回退到最近健康模型和阈值,高风险切片临时增加规则拦截或人工全量复核。
  • 长期修复:明确错判成本,使用验证集选择阈值,补充困难正类并校准概率;模型、阈值和规则共同版本化。
  • 回归验证:在冻结测试集上比较正类 Recall、Precision、PR-AUC、校准与人工队列容量,并检查其他语言和内容类型没有回归。
  • 防复发:发布门禁强制报告业务关键切片;线上监控漏审抽检、分数分布、规则冲突和阈值漂移。

7.5 监控、测试与复盘

  • 数据:缺失率、取值范围、类别占比、未知类别、输入漂移;
  • 模型:分数分布、校准、按切片 Precision/Recall、错误样本;
  • 决策:各队列数量、人工容量、规则与模型冲突、阈值版本;
  • 系统:延迟、超时、模型加载失败、回退比例、特征服务错误;
  • 测试:特征契约、Pipeline 边界、同源/时间切分、阈值回归、模型序列化和离在线一致性。

示例不预填效果。真实复盘必须列出基线、候选方案、固定评测集、置信区间、分切片、错误类型、资源开销和发布验证,并说明哪些变化来自模型、阈值或规则。

8. 方案权衡与常见误区

8.1 模型选择不是排行榜选择

约束或现象优先考虑进一步验证
稀疏高维、需系数解释正则化逻辑回归非线性残差、概率校准
表格特征有阈值与交互决策树/Boosting深度、学习率、早停和泄漏
单树不稳定Random Forest/Bagging树相关性、模型大小、推理延迟
小数据且高维线性/核方法、强正则交叉验证方差和特征选择泄漏
原始图像/音频/视频预训练表示 + 简单头或深度模型表示迁移、资源、端到端收益证据

8.2 过拟合与欠拟合的诊断

  • 训练与验证都差:目标/特征不可学、容量不足、优化失败或标签噪声;
  • 训练好而验证差:容量过高、泄漏边界错误、样本少或分布差异;
  • 训练和验证都好但测试差:验证集过拟合、测试口径/分布不同;
  • 离线都好而线上差:训练/服务偏差、特征延迟、分布漂移或反馈回路;
  • 学习曲线比单个分数更有诊断价值:增加数据后训练/验证差距怎样变化,能帮助区分容量和数据问题。

8.3 常见错误回答

  • “随机森林就是很多树,所以一定不会过拟合”——相关树、噪声和不当深度仍有风险;
  • “Boosting 每轮拟合上轮预测错误的标签”——更准确地说是拟合当前损失的负梯度/残差;
  • “AUC 不受类别不平衡影响,所以足够”——排序统计仍可算,但业务误报、PR 和概率先验不能省略;
  • “F1 越高业务越好”——F1 不含 TN,也未表达具体成本和容量;
  • “采样后验证分数更好”——若验证集也被重采样,指标不再代表真实分布;
  • “树模型不需要预处理”——通常不需标准化,但仍需缺失、类别、泄漏和离在线一致性治理。

8.4 生产排障优先级

  1. 确认正类、标签窗口、阈值和业务动作口径;
  2. 对齐训练与服务特征的值、顺序、单位、缺失和版本;
  3. 检查切分、预处理和采样泄漏;
  4. 比较输入、标签先验、概率与误差切片漂移;
  5. 检查模型容量、正则、树深、学习率和早停;
  6. 将根因样本固化为黄金样本或回归切片,防止只修一次。

9. 面试题与参考答案

问题 1:逻辑回归为什么叫“回归”,却用于分类?

  • 难度:基础;
  • 考察点:概率建模和决策边界;
  • 合格答案要点:它回归的是正类对数几率的线性函数,经 Sigmoid 得到概率,再用阈值分类;
  • 优秀答案加分项:写出 log-odds 公式、交叉熵和线性决策边界,区分概率估计与业务决策;
  • 常见错误:说它先做线性回归再把结果截断;
  • 可继续追问:加入多项式特征后决策边界还是线性吗?

问题 2:类别极不平衡时为什么不能只看 Accuracy?

  • 难度:基础;
  • 考察点:混淆矩阵与业务代价;
  • 合格答案要点:全预测多数类也可能得到高 Accuracy,却没有检出少数正类;应看 Precision、Recall、PR 和成本;
  • 优秀答案加分项:讨论校准、阈值、真实先验、分切片与人工容量;
  • 常见错误:机械地说“用 F1 就够了”;
  • 可继续追问:何时应优化 Recall@Precision≥某值,而不是 F1?

问题 3:决策树为什么容易过拟合,怎么处理?

  • 难度:中级;
  • 考察点:树的递归划分与方差;
  • 合格答案要点:深树可生成很小叶子拟合噪声,对样本变化敏感;限制深度、叶节点样本、剪枝或集成;
  • 优秀答案加分项:区分预剪枝、后剪枝、Bagging 降方差和 Boosting 的串行拟合;
  • 常见错误:认为树不用优化所以不会过拟合;
  • 可继续追问:为何随机特征子集可以改善随机森林?

问题 4:Bagging 和 Boosting 的本质区别是什么?

  • 难度:中级;
  • 考察点:偏差—方差与训练依赖;
  • 合格答案要点:Bagging 大体并行训练并平均,主要降低高方差;Boosting 串行加入弱学习器拟合当前残差/负梯度,主要降低偏差;
  • 优秀答案加分项:写出平均方差受模型相关性限制,以及 Boosting 的加法模型与收缩;
  • 常见错误:只说一个并行一个串行,不解释为什么有效;
  • 可继续追问:噪声标签多时两者的风险有何不同?

问题 5:AUC 很高但线上效果差,如何排查?

  • 难度:高级;
  • 考察点:排序、校准、阈值和线上链路;
  • 合格答案要点:核对正类/窗口、阈值和成本,检查校准、切片、漂移、特征离在线一致性;
  • 优秀答案加分项:区分 ROC-AUC 与 PR-AUC,检查概率先验、容量约束、服务回退和反馈闭环;
  • 常见错误:直接换模型或继续提高 AUC;
  • 可继续追问:模型排序不变但类先验变化时,Precision 和阈值会怎样?

10. 递进追问

10.1 追问清单

  1. 基础概念:为什么 Sigmoid 输出可以解释为概率,训练后又为何可能不校准?
  2. 原理细节:逻辑回归与交叉熵组合后梯度为什么简化为 XT(py)/n
  3. 实现边界:类别权重、过采样和阈值移动分别改变了训练或决策的哪一层?
  4. 工程权衡:随机森林树数增多时,效果、延迟、内存和可解释性如何变化?
  5. 系统设计:怎样实现模型、预处理、特征、校准器和阈值的一体化版本与回滚?
  6. 项目复盘:一次“离线 AUC 上升、线上人工通过率下降”的改版应如何复盘并建立防回归门禁?

10.2 回答检查点

  1. Sigmoid 是 Bernoulli 条件概率的参数化;有限数据、正则、采样和漂移会使概率失准;
  2. 展开链式法则,Sigmoid 导数与交叉熵分母抵消,得到 py
  3. 权重/采样改变训练目标或数据分布,阈值移动只改变同一分数下的决策;
  4. 更多树降低平均中的随机方差直到相关性下限,但线性增加模型大小和推理计算;
  5. 以单一制品或清单绑定所有版本,黄金样本做离在线一致性,灰度可快速回滚;
  6. 还原正类、窗口、阈值、容量和规则变化,按切片分析,并把事故样本加入固定回归集。

11. 实践任务

  • [ ] 最小实现:运行第 6 节代码,手推逻辑回归梯度并与更新代码逐行对应;
  • [ ] 阈值实验:输出验证集不同阈值的混淆矩阵,说明阈值如何移动 Precision/Recall;
  • [ ] 不平衡实验:减少合成正类,比较 Accuracy、F1 和 PR 相关指标的解释差异;
  • [ ] 模型对比:使用同一冻结切分比较逻辑回归、限制深度树和集成模型,记录错误类型而非只排名;
  • [ ] 故障注入:在切分前对全量数据标准化,解释为何代码能运行但评测有偏;
  • [ ] 面试口述:用 1 分钟回答模型选择,再接受“为何不用深度学习”和“AUC 高为何不够”追问。

验收标准:能从业务代价选择指标与阈值;能解释三类模型的归纳偏置;能给出离线到线上质量下降的可执行排查树。

12. 相关知识与参考资料

12.1 相关知识

12.2 参考资料

以下仅使用原始论文和官方文档,访问日期均为 2026-07-10

  1. scikit-learn, Linear Models,官方文档;
  2. scikit-learn, Decision Trees,官方文档;
  3. scikit-learn, Ensembles: Gradient boosting, random forests, bagging,官方文档;
  4. scikit-learn, Metrics and scoring: quantifying the quality of predictions,官方文档;
  5. scikit-learn, Probability calibration,官方文档;
  6. Breiman, Random Forests,原始论文;
  7. Friedman, Greedy Function Approximation: A Gradient Boosting Machine,原始论文 DOI;
  8. Chen and Guestrin, XGBoost: A Scalable Tree Boosting System,原始论文。

本次技术栈横评另核对 scikit-learn Pipelines and composite estimators 官方文档,访问日期为 2026-07-11

13. 简明总结

一句话记忆: 传统机器学习的核心不是背模型名,而是让归纳偏置、数据边界、评测指标和业务决策彼此对齐。

  • 逻辑回归学习线性 log-odds,树递归划分空间,Bagging 降方差,Boosting 串行修正损失;
  • Accuracy、AUC、F1 都不是万能指标,必须回到正类、阈值、概率校准和误判代价;
  • 预处理、采样和特征选择只能在训练数据中拟合,验证选方案,测试做终评;
  • 生产最常见问题是泄漏、类别/先验漂移、离在线特征不一致和阈值版本脱节;
  • 面试时先给简单基线,再用错误分析和约束证明为什么升级模型。

最后更新: