面试八股——机器学习

基础概念

监督学习、半监督学习和无监督学习

1. 监督学习 (Supervised Learning)

  • 核心特点:数据既有特征(Features),也有标签(Labels)。即每个 X 都有对应的 Y
  • 工作原理:模型通过学习输入 X 到输出 Y 的映射关系,来预测未知数据。
  • 经典任务
    • 分类 (Classification):预测离散值(如垃圾邮件分类、多模态暴力行为检测)。
    • 回归 (Regression):预测连续值(如股票/期货价格预测)。

2. 无监督学习 (Unsupervised Learning)

  • 核心特点:数据只有特征(Features),没有标签(Labels)。只有 X,没有 Y
  • 工作原理:模型不依赖外界引导,而是依靠算法自身去挖掘数据的内在结构、相似性或潜在模式。
  • 经典任务
    • 聚类 (Clustering):把相似的数据聚集在一起(如 K-Means、用户画像分群)。
    • 降维 (Dimensionality Reduction):压缩数据特征,去除冗余(如 PCA、t-SNE)。
    • 自监督学习 (Self-Supervised Learning):现代大模型(LLM)基座预训练的核心。本质上是从无标签数据中自己构造标签(比如掩码语言模型 Masked LM,抠掉一个词让模型预测,这个词就是标签)。

3. 半监督学习 (Semi-Supervised Learning)

  • 核心特点:介于两者之间。通常是极少量的标注数据 + 大量的无标注数据
  • 为什么需要:在实际工程中,标注数据极其昂贵且耗时,而无标注数据极易获取。半监督学习旨在利用海量无标注数据包含的分布信息,来辅助提升小规模标注数据的分类性能。
  • 常见方法
    • 伪标签 (Pseudo-Labeling):先用标注数据训练一个基础模型,用它去预测无标签数据,把置信度高的预测结果当做“真标签”喂回模型重新训练。
    • 一致性正则 (Consistency Regularization):对同一个无标签输入做不同的数据增强(如加噪声),约束模型的输出保持一致。

机器学习任务

监督学习任务

  • 分类 (Classification):目标变量是离散的标签
    • 二分类:判断邮件是否为垃圾邮件、判断文本是否包含暴力行为。
    • 多分类/多标签:图像物体识别、给一篇文章贴多个领域标签。
  • 回归 (Regression):目标变量是连续的数值
    • 预测未来走势:如房价预测、股票/期货价格预测。

无监督学习任务

  • 聚类 (Clustering):无监督地将相似样本归为一类(如 K-Means、层次聚类)。
  • 降维 (Dimensionality Reduction):在高维特征空间中提炼低维特征(如 PCA、t-SNE),常用于特征降噪和数据可视化。
  • 异常检测 (Anomaly Detection):寻找与绝大多数数据显著不同的极少数样本(如信用卡盗刷、工业设备故障检测)。

常见的损失函数

一、 回归任务(Regression Loss)

用于预测连续数值(如房价预测、期货价格走势)。

1. MSE (Mean Squared Error) 均方误差 / L2 损失

  • 公式

    $$\text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$

  • 特点:对异常值(Outliers)极其敏感。因为平方项的存在,如果一个样本预测偏了,误差会被无限放大。

  • 缺点:如果数据集中有很多脏数据(噪声),模型会被异常值带偏。

2. MAE (Mean Absolute Error) 平均绝对误差 / L1 损失

  • 公式

    $$\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|$$

  • 特点:对异常值具有很强的鲁棒性(Robust),误差的影响是线性的。

  • 缺点:在 y =  处(即误差为0的点)不可导,在训练后期(接近最优点时)可能会在最小值附近震荡,不易收敛。

3. Huber Loss (平滑的 L1 损失)

  • 核心思想:结合了 MSE 和 MAE 的优点。
  • 工作机制:当误差较小时,使用 MSE(保证梯度平滑、快速收敛);当误差较大(遇到异常值)时,自动切换为 MAE(降低敏感度,保护模型)。

二、 分类任务(Classification Loss)

用于预测离散的类别标签。

1. 二分类交叉熵损失 (Binary Cross-Entropy, BCE)

  • 公式

    $$\text{BCE} = -\frac{1}{n} \sum_{i=1}^{n} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]$$

  • 适用场景:判断题(是/否),或者多标签分类(一个样本可以同时属于多个独立类别)。

  • 搭配激活函数:网络最后一层通常搭配 Sigmoid,将输出映射到 (0, 1) 区间。

2. 多分类交叉熵损失 (Categorical Cross-Entropy, CCE)

  • 公式

    $$\text{CCE} = -\sum_{c=1}^{C} y_c \log(\hat{y}_c)$$

    (其中 C 为类别总数)

  • 适用场景:单选多分类(如经典的 MNIST 手写数字识别 0~9,或是判别一段文本是否属于暴力行为)。

  • 搭配激活函数:网络最后一层必须搭配 Softmax,使所有类别的预测概率之和等于 1。

偏差(Bias)与方差(Variance)

欠拟合对应“高偏差,低方差”。模型本身偏离了真实规律,但由于简单,在不同数据集上表现都很稳定的差。

过拟合对应“低偏差,高方差”。模型对训练集拟合得极好(偏差低),但因为对数据太敏感,换一个数据集它的预测结果就会发生剧烈抖动(方差高)。

如何应对过拟合问题?

1. 数据层面 (Data Level)

  • 增加训练数据量:这是解决过拟合最直接、最根本的手段。数据量足够大、覆盖面足够广时,模型就很难“死记硬背”噪声。
  • 数据增强 (Data Augmentation):如果无法获取新数据,可以通过对现有数据进行变换(如图像旋转、裁剪、NLP中的同义词替换、多模态中引入轻微干扰)来人为制造“新数据”,提高模型的鲁棒性。

2. 模型架构与复杂度层面 (Model Level)

  • 降低模型复杂度:减少神经网络的层数(Depth)或隐藏单元数(Width),或者在使用传统机器学习(如决策树)时限制树的深度。
  • 引入正则化 (Regularization)
    • L1 正则化 (Lasso):在损失函数中加入权重绝对值之和(λ∑|w|),会使不重要的参数变为 0,从而产生稀疏解,起到特征选择的作用。
    • L2 正则化 (Ridge / 权重衰减):在损失函数中加入权重平方和($\frac{\lambda}{2} \sum w^2$),惩罚过大的权重值,让模型的参数分布更平滑,防止个别特征权重过大。
  • Dropout (深度学习特有):在每次前向传播时,随机让一定比例(如 50%)的神经元失活(输出置零)。强制网络不能依赖某几个特定的神经元组合,从而学习到更具鲁棒性的集成特征。

3. 训练策略层面 (Optimization Level)

  • 早停法 (Early Stopping):在训练过程中同时监控验证集的 Loss。当发现训练集 Loss 还在下降,但验证集 Loss 已经开始不降反升时,立即终止训练,保存验证集效果最好的那一代参数。
  • 交叉验证 (Cross-Validation):如 K-Fold 交叉验证,确保评估结果不受单一特定划分的测试集影响,让调参和模型选择更准确。
  • 集成学习 (Ensemble Learning):将多个基模型的预测结果进行组合(如 Bagging 算法、Random Forest),利用“集体智慧”抵消单个模型可能产生的过拟合风险。

正则化

什么是正则化?

定义:正则化是指在机器学习模型的目标函数(Loss Function)中引入额外约束/惩罚项的技术。

机器学习/深度学习中常见的正则化方法

在面试中,建议将方法划分为传统数学惩罚现代深度学习策略两部分来作答。

1. 传统数学惩罚项(在原 Loss 后面直接加项)

L1 正则化 (Lasso 回归)
  • 做法:在损失函数后面加上所有权重参数的绝对值之和

    $$\text{Total Loss} = \text{Original Loss} + \lambda \sum_{j=1}^{d} |w_j|$$

  • 作用与特点:会产生稀疏解(Sparse Solution)。它会无情地将很多不重要特征的权重直接削减为 0

  • 面试金句L1 正则化自带特征选择(Feature Selection)功能。” 因为在几何上,L1 的等高线是一个带尖角的方形,原 Loss 极值通常会在坐标轴(即某个 w = 0 的地方)与它相交。

L2 正则化 (Ridge 岭回归 / Weight Decay 权重衰减)
  • 做法:在损失函数后面加上所有权重参数的平方和

    $$\text{Total Loss} = \text{Original Loss} + \frac{\lambda}{2} \sum_{j=1}^{d} w_j^2$$

  • 作用与特点:会产生平滑解。它不会把权重减到 0,而是倾向于让所有的 w尽可能地接近 0 但不等于 0(惩罚大权重)。

  • 面试金句L2 正则化让模型参数分布更均匀,避免单个特征独大。” 当输入发生轻微扰动时,因为 w 都很小,输出就不会产生剧烈震荡,从而降低了方差。

梯度下降有哪些变体?

1. 批量梯度下降 (Batch Gradient Descent, BGD)

  • 工作机制:每次更新参数时,使用整个训练集的所有样本来计算梯度。
  • 优点:梯度的计算方向非常准,由于利用了全量数据,曲线下降过程非常平滑,只要学习率合适,一定能收敛到全局最优(凸问题)或局部最优(非凸问题)。
  • 缺点太慢了! 如果数据集有几百万条,每更新一次参数都要把所有数据算一遍,算力和内存/显存根本吃不消。

2. 随机梯度下降 (Stochastic Gradient Descent, SGD)

  • 工作机制:每次更新参数时,随机抽取一个样本来计算梯度并更新。
  • 优点:计算速度极快,内存占用极小。由于单个样本具有随机性,它的梯度方向总是“晃晃悠悠”的,这种随机噪声反而有助于模型跳出某些局部最优解或鞍点
  • 缺点:准确度低。即使到了山谷底部,它也不会安分停下,而是在最低点附近剧烈震荡,很难达到完美的收敛状态。

3. 小批量梯度下降 (Mini-batch Gradient Descent)

  • 工作机制:前两者的折中。每次更新参数时,使用一小批样本(一个 Batch,如 32, 64, 128, 256)来计算梯度。
  • 现代深度学习的标准做法
    • 融合了 BGD 的稳定:利用 Batch 数据的平均梯度,方向比纯 SGD 稳定得多,曲线相对平滑。
    • 融合了 SGD 的高效:不需要载入全量数据,可以完美利用 GPU 的矩阵并行计算能力。

线性与概率模型

线性回归

1. 建立模型方程

对于一个多特征的样本 X = [x1, x2, ..., xd]T,模型通过赋予每个特征不同的权重 w,再加上一个偏置 b,来计算出预测值

 = w1x1 + w2x2 + ... + wdxd + b

2. 定义损失函数:最小二乘法 (OLS)

我们如何评价这条“线”画得好不好?标准做法是计算均方误差(MSE)。我们希望所有样本的预测值与真实值之间的平方差之和最小:

$$L(W, b) = \frac{1}{2n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$

注:为什么要用平方?一是为了消去正负号的影响,二是平方项在数学上处处可导,非常方便计算。

3. 参数求解(怎么找到最完美的 wb

在面试中,求解方法一定要答出以下两条完全不同的路径

  • 路径 A:闭式解(解析解)—— 矩阵直接求导

    将一整套数据集写成矩阵形式,对损失函数求偏导并直接令偏导等于 0。在数学上可以一步到位直接推导出最优解公式:

    W = (XTX)−1XTY

    • 面试追问点:只有当 XTX 满秩且可逆时,才能用这个公式。如果特征之间高度相关(多重共线性),矩阵就会不可逆。此时必须引入 L2 正则化(岭回归)来强制使其可逆。
  • 路径 B:数值解 —— 梯度下降法

    当特征维度或数据量极端庞大时(比如大模型和现代深度学习场景),矩阵求逆的计算复杂度极高(O(d3))。此时我们会转而采用梯度下降法,顺着梯度的反方向一步步更新 Wb,直到模型收敛。

线性回归(Linear Regression)逻辑回归(Logistic Regression)

维度 线性回归 (Linear Regression) 逻辑回归 (Logistic Regression)
任务本质 回归(Regression)任务。 分类(Classification)任务。
输出形式 连续值。范围为 (−∞, +∞)(如预测房价、股票价格)。 离散值/概率值。范围严格限制在 (0, 1) 之间,表示属于某一类的概率。
激活函数 无(或者说是线性的 f(x) = x)。 Sigmoid 函数(将输出映射到概率区间)。
损失函数 均方误差 (MSE) / 最小二乘法。 交叉熵损失 (Cross-Entropy) / 负对数似然。

在数学和逻辑上,逻辑回归本质上是在线性回归的基础上套了一层“外壳”

逻辑回归分别是怎样处理二分类问题和多分类问题的?

直接升级为多项逻辑回归(Softmax 回归)

这是最本质、最优雅的扩展方式。当二分类的逻辑回归遇到多分类时,Sigmoid 函数会直接升级为 Softmax 函数

机制

  1. 模型不再只有一根线性输出线,而是针对 K 个类别分别拉出 K 根线,计算出 K 个类别的得分:[z1, z2, ..., zK]

  2. 使用 Softmax 函数 将这 K 个得分进行归一化,转化为一个概率分布

    $$P(y=c|X) = \frac{e^{z_c}}{\sum_{j=1}^{K} e^{z_j}}$$

  3. Softmax 的魔法在于:所有类别算出来的概率之和严格等于 1。模型最终选择概率最大的那个类别作为预测结果。

极大似然估计(MLE)

“简单来说,极大似然估计就是利用已经发生的事实(数据),去反推最有可能导致这个事实发生的一组模型参数(权重 w)。”

  • 传统概率:已知参数(比如硬币是均匀的),去预测未来的结果(抛 10 次大概有 5 次正面)。
  • 极大似然:结果已经摆在桌子上了(抛了 10 次硬币,结果 9 次正面 1 次反面),现在我们要反推参数(这枚硬币大概率被灌铅了,正面概率 w = 90% 左右最合理)。

准备工作:设定场景与符号

假设我们手头有一个二分类数据集,样本之间是独立同分布 (i.i.d.) 的。

  • 每个样本的真实标签 yi ∈ {0, 1}
  • 模型预测它为 1 的概率为 pi(在逻辑回归中 pi = σ(wTxi))。
  • 那么,模型预测它为 0 的概率自然就是 1 − pi

我们可以把这两个情况合并成一个优雅的单一样本概率公式(伯努利分布的概率质量函数):

P(yi|xi; w) = piyi(1 − pi)1 − yi

小思考:验证一下这个公式。如果真实标签 yi = 1,代入后半部分变成 (1 − pi)0 = 1,整体就剩 pi1 = pi;同理,若 yi = 0,整体就剩 1 − pi。非常完美。

数学推导三步走

现在我们要利用这个单一样本的概率,去反推最完美的权重 w

第一步:构建似然函数 L(w) —— 求总概率

由于所有样本相互独立,这 n 个样本同时发生的“总概率”,就是把所有单一样本的概率全部乘起来

$$L(w) = \prod_{i=1}^{n} P(y_i | x_i; w) = \prod_{i=1}^{n} p_i^{y_i} (1 - p_i)^{1 - y_i}$$

这个 L(w) 就是似然函数。我们的终极目标是找到一个 w,让这个连乘的总概率最大。

第二步:取对数 ln  —— 连乘变连加

直接对连乘求导会触发数学灾难(高阶乘积求导极其复杂),而且计算机会发生浮点数下溢。所以我们两边同时取自然对数 ln 

$$\ln L(w) = \ln \left( \prod_{i=1}^{n} p_i^{y_i} (1 - p_i)^{1 - y_i} \right)$$

根据对数的性质 ln (a ⋅ b) = ln a + ln b 以及 ln (ab) = bln a,我们可以把连乘的大括号拆开,变成连加

$$\ln L(w) = \sum_{i=1}^{n} \left[ y_i \ln p_i + (1 - y_i) \ln(1 - p_i) \right]$$

这就是著名的对数似然函数 (Log-Likelihood)

第三步:求偏导并令其为 0 —— 寻找极值点

为了让总概率最大,我们需要对权重 w 求偏导。这里需要用到高等数学的链式求导法则(由于 pi 内部含有 w):

$$\frac{\partial \ln L(w)}{\partial w} = 0$$

在传统的统计学中,我们解出这个方程,得到的 w 就是极大似然估计值。

交叉验证

拆解 K 折交叉验证的工作原理(以 5 折为例)

正如你所说,它的标准执行步骤非常具有仪式感,我们可以通过图解和“轮班制”来理解:

  1. 第一步(分块):把原始数据集随机打乱,并平均分成 K 个互不重叠的块(Folds)。比如我们选 K = 5,数据集就被均分为 块1、块2、块3、块4、块5。
  2. 第二步(轮流站岗):我们要进行 5 轮训练和测试
    • 第 1 轮:拿 块1 作为验证集,剩下的 块2, 3, 4, 5 合并作为训练集。训练模型,得到一个评估得分 S1
    • 第 2 轮:拿 块2 作为验证集,剩下的 块1, 3, 4, 5 作为训练集。得到得分 S2
    • ……
    • 第 5 轮:拿 块5 作为验证集,剩下的 块1, 2, 3, 4 作为训练集。得到得分 S5
  3. 第三步(大和解):把这 5 轮算出来的得分求一个平均值 Mean(S1, S2, ..., S5)这个平均分,才是我们最终认定的模型真实泛化能力。

1. 分层 K 折交叉验证 (Stratified K-Fold)

  • 对应场景样本极度不均衡。 比如你在做多模态暴力行为检测,1 万条视频里只有 100 条是暴力的(只占 1%)。
  • 做法:如果用普通 K 折,随机盲抽可能会导致某些块(Fold)里全是正常视频,一个暴力视频都没有,模型直接学不会。分层 K 折在切块时,会强迫每一个块内部的正负样本比例,都严格保持原数据集的 1:99

2. 留一法 (Leave-One-Out, LOOCV)

  • 对应场景数据量极其稀少(比如只有几十个样本)。
  • 做法:如果总共有 N 个样本,那我们就搞 N 折交叉验证。每次只把 1 个样本扣出来当验证集,剩下的 N − 1 个全部用来训练。 这样要重复跑 N 次模型。
  • 优缺点:几乎用尽了所有数据去训练,结果最精准;但如果大模型或者数据量稍大一点,算力根本承受不起,计算量爆炸。

Ridge 回归(岭回归)Lasso 回归

一、 Ridge 回归(岭回归 / L2 正则化)

Ridge 回归是在标准线性回归的均方误差(MSE)损失函数后面,加上了权重参数的平方和(称为 L2 范数惩罚项)。

1. 数学公式

$$\text{Loss}_{\text{Ridge}} = \frac{1}{2n} \sum_{i=1}^{n} (y_i - w^T x_i)^2 + \frac{\lambda}{2} \sum_{j=1}^{d} w_j^2$$

  • λ(正则化系数)用来控制惩罚的力度。λ 越大,紧箍咒越紧。

2. 工作原理与“性格”

  • 整体平滑压制L2 惩罚项对极大的权重惩罚非常严厉(因为有平方)。这会逼迫梯度下降在更新参数时,把所有的权重 w尽可能地往 0 的方向压,但绝对不会让它们真正等于 0
  • 物理意义:它让模型的参数分布变得非常均匀且平滑,避免了单个特征独大。这样当输入数据有轻微风吹草动(噪声)时,输出不会剧烈晃动,从而降低了方差。
  • 经典作用:完美解决多重共线性问题。当特征之间高度相关时,传统的线性回归矩阵求逆会崩溃,而 Ridge 回归在数学上强行保证了逆矩阵必然存在且稳定。

二、 Lasso 回归(L1 正则化)

Lasso 回归则是在 MSE 损失函数后面,加上了权重参数的绝对值之和(称为 L1 范数惩罚项)。

1. 数学公式

$$\text{Loss}_{\text{Lasso}} = \frac{1}{2n} \sum_{i=1}^{n} (y_i - w^T x_i)^2 + \lambda \sum_{j=1}^{d} \vert{}w_j\vert{}$$

2. 工作原理与“性格”

  • 无情裁剪(稀疏解)L1 惩罚项对大权重和小权重的惩罚力度是恒定的(斜率固定)。在优化过程中,它会表现得非常无情,直接把很多不重要、或者贡献小的特征的权重 w 削减到严格的 0
  • 物理意义:训练完成后,你会得到一个非常“稀疏”的权重矩阵(里面充斥着大量的 0)。
  • 经典作用自带特征选择(Feature Selection)功能。如果你的数据有 1000 个特征,Lasso 跑完可能只有 50 个特征的 w 不为 0,剩下 950 个特征直接被它无视了。这极大提升了模型在大数据场景下的可解释性和运行效率。

贝叶斯定理

$$P(\theta\vert{}X) = \frac{P(X\vert{}\theta) \cdot P(\theta)}{P(X)}$$

  • P(θ) —— 先验概率 (Prior):在没有看到新数据之前,你对这件事情发生可能性的固有认知或主观猜测。
  • P(X|θ) —— 似然概率 (Likelihood):就是我们刚刚反复聊到的“利用概率反推权重”里的那个概率。如果我的假设 θ 是对的,那么出现眼前这批数据 X 的可能性有多大?
  • P(X) —— 边缘概率/标准化常量 (Evidence):无论你的假设是什么,这批数据 X 自身发生的总概率。在很多时候它只是一个分母,用来把结果缩放到 0~1 之间。
  • P(θ|X) —— 后验概率 (Posterior)核心目标。在看到了新数据 X 之后,我们更新过后的新认知

朴素贝叶斯

回到贝叶斯公式,我们要预测一个新样本(比如一封邮件 X)属于某个类别(比如垃圾邮件 C1)的概率:

$$P(C_1 \vert{} X) = \frac{P(X \vert{} C_1) P(C_1)}{P(X)}$$

这里的特征 X 通常包含很多个维度,比如一封邮件里包含了词汇 [x1 = “发票”, x2 = “中奖”, x3 = “点击”]

在现实生活中,这些词之间明显是有关联的。但是,如果我们要去计算它们复杂的联合概率 P(“发票”, “中奖”, “点击”|C1),在数学上需要海量的数据才能统计出来,甚至会发生维度灾难。

为了打破这个僵局,朴素贝叶斯提出了一个近乎弱智、极其天真的假设 —— 特征条件独立假设(这也就是“朴素”的由来)

“它假设所有的特征之间是完全独立的、互不影响的。”

有了这个“朴素”的假设,原本极其难算的联合概率,在数学上就可以直接简单粗暴地拆解为各自概率的连乘

P(X|C1) = P(“发票”|C1) × P(“中奖”|C1) × P(“点击”|C1)

树模型与集成学习

信息增益,信息增益率

信息增益 (Information Gain) —— 初代鼻祖(ID3 标配)

要理解信息增益,必须先了解信息熵(Entropy)。信息熵是香农提出的,用来量化数据的混乱程度

📊 数学公式

对于一个数据集 D,假设里面有 K 个类别,每个类别占的比例是 pk,那么它的信息熵为:

$$\text{Entropy}(D) = - \sum_{k=1}^{K} p_k \log_2 p_k$$

  • 当数据全是一类时(纯度最高),Entropy = 0
  • 当数据各类别均匀分布时(最混乱),Entropy 达到最大值。

信息增益就是:分裂前的总熵,减去分裂后各子节点熵的加权和

$$\text{Gain}(D, A) = \text{Entropy}(D) - \sum_{v=1}^{V} \frac{\vert{}D^v\vert{}}{\vert{}D\vert{}} \text{Entropy}(D^v)$$

💡 通俗理解

信息增益代表了“得知某个特征后,系统混乱度下降了多少”。增益越大,说明这个特征分得越好,系统越快变整齐。

信息增益率 (Gain Ratio) —— 修复补丁(C4.5 标配)

为了死死卡住 ID3 偏向多取值特征的 Bug,C4.5 引入了信息增益率

📊 数学公式

信息增益率在信息增益的分子基础上,强行除以了一个分母 —— 特征自身的内在熵(Split Info)

$$\text{Gain\_ratio}(D, A) = \frac{\text{Gain}(D, A)}{\text{SplitInfo}_A(D)}$$

其中分母 $\text{SplitInfo}_A(D) = - \sum_{v=1}^{V} \frac{\vert{}D^v\vert{}}{\vert{}D\vert{}} \log_2 \frac{\vert{}D^v\vert{}}{\vert{}D\vert{}}$

💡 通俗理解

特征的取值越多、分出来的枝丫越零碎,这个特征自身的“内在熵(分母)”就会暴涨

作为分母,它就像一个无情的惩罚项。即使一个特征(比如身份证号)的信息增益很大,但因为它的取值太多导致分母极大,最终算出来的“信息增益率”也会被狠狠地拉低。从而完美抑制了过拟合。

ID3 构造决策树的五步算法流程

步骤 1:准备输入与边界检查(递归基判定)

算法传入当前的数据集 D 和剩余的特征集 A。在开始算数学公式前,先做三项“安全检查”,看是否能直接收敛为叶子节点

  • 检查 A:如果 D 中所有样本都属于同一个类别 Ck,不用分了,直接把当前节点标记为类别 Ck 的叶子节点,返回。
  • 检查 B:如果特征集 A 已经空了(特征用完了),或者 D 中所有样本在剩下特征上的取值都一模一样(无法再分),那就“少数服从多数”,把当前节点标记为 D 中样本数最多的类别的叶子节点,返回。

步骤 2:计算当前数据集的总体混乱度(总信息熵)

如果检查通过,说明需要继续分裂。首先计算当前数据集 D信息熵 H(D),作为分裂前的基准混乱度:

$$H(D) = - \sum_{k=1}^{K} p_k \log_2 p_k$$

(其中 pk 是第 k 个类别在当前数据集中的样本占比。)

步骤 3:挑选最佳分裂特征(计算信息增益)

遍历当前剩下所有特征。对于每一个特征 g

  1. 假设按特征 g 的所有可能取值,把数据集 D 划分成了多个子集 D1, D2, ..., DV

  2. 计算划分后的条件熵(即所有子集混乱度的加权平均):

    $$H(D\vert{}g) = \sum_{v=1}^{V} \frac{\vert{}D^v\vert{}}{\vert{}D\vert{}} H(D^v)$$

  3. 算出该特征的信息增益Gain(D, g) = H(D) − H(D|g)

  4. 决策判定:对比所有特征,挑出信息增益最大的那一个特征,作为当前节点的核心分裂特征 Abest

步骤 4:长出分支,切分数据集

针对挑选出的最佳特征 Abest,它有多少个可能的取值,就从当前节点向下拉出多少个对应的子分支(多叉树结构)。根据取值将数据集 D 划分到各个子节点中。

步骤 5:递归向下构建

对每一个子节点,把已经用掉的特征 Abest 从特征集中剔除,然后将子节点的数据集和缩减后的特征集重新喂回“步骤 1”,直到所有分支都触碰到叶子节点。

决策树算法是如何应对欠拟合和过拟合的

一、 决策树如何应对【过拟合】?

过拟合在决策树上的表现是:树长得太深、太茂盛,方差(Variance)极高,完美拟合训练集噪声,测试集一塌糊涂

应对过拟合,单棵决策树的核心武器是“剪枝(Pruning)”,分为预剪枝和后剪枝:

1. 预剪枝(Pre-pruning)—— 提前叫停

在树的生长过程中,只要满足某些设定的硬性阈值,就直接强行停止分裂,让其直接退化为叶子节点。

  • 限制最大深度(max_depth:这是最直观的限制,强制树高不能超过指定的层数。
  • 限制叶子节点所需最小样本数(min_samples_leaf:如果某个分支切完后,子节点里的样本数少于 5 个,就不允许再切了。
  • 限制分裂所需最小样本数(min_samples_split:如果一个节点自己包含的样本数已经很少了,直接放弃继续往下分。
  • 设置最小信息增益阈值:如果切完这刀,信息熵降低的幅度(信息增益)达不到规定标准,说明这刀不划算,不切了。
  • 优点:计算效率极高,省时省算力。
  • 缺点:非常盲目,容易带来欠拟合(因为你不知道当前的微小增益,会不会在下一次分裂时带来巨大的纯度飙升,即“视界局限”)。

2. 后剪枝(Post-pruning)—— 斩草除根

先让整棵树憋着一股劲完全长完(直到熵归 0),然后使用验证集,从下往上审视每一个非叶子节点。如果把这个节点的子树全部砍掉、直接退化为叶子节点后,验证集的准确率没有下降甚至上升了,那就果断挥刀把子树砍掉。

  • 典型算法:代价复杂度剪枝(CCP, Cost-Complexity Pruning)。它在损失函数中加入了一个关于叶子节点个数的惩罚项:

    Rα(T) = R(T) + α|Tf|

    通过调节 α,在“训练误差 R(T)”与“树的复杂程度(叶子数 |Tf|)”之间找到完美的平衡。

  • 优点:泛化能力极强,保留了真正有效的长远规则,防过拟合效果极佳。

  • 缺点:需要把树完整建好再反向遍历,算力和时间开销非常大。

二、 决策树如何应对【欠拟合】?

欠拟合在决策树上的表现是:树长得太矮、太粗糙,偏差(Bias)极高,模型在训练集和测试集上的准确率都很低

应对欠拟合的思路非常直接 —— 为模型松绑,增加模型的表达容量

  1. 放宽剪枝限制
    • 调大最大深度 max_depth
    • 调小叶子节点或分裂所需的最小样本数(min_samples_leaf / min_samples_split)。
    • 将最小信息增益阈值直接调低或设为 0,允许模型去敏锐地捕捉更加微弱的特征变化。
  2. 特征工程升级
    • 决策树如果欠拟合,很可能是当前的自变量特征根本不足以划分出正负样本。需要引入更多的交互特征(Interaction Features)、衍生特征,或者对连续特征使用更细致的离散化方案。
  3. 更换分裂指标
    • 如果你在用初代 ID3 算法,由于它无法处理连续值和缺失值,极易在复杂任务中欠拟合。此时需要无脑升级到支持连续值和二分的 C4.5CART 算法。

Boosting 算法和 Bagging 算法

维度 Bagging (自举汇聚法) Boosting (提升法)
构建方式 并行(Parallel)。各个弱学习器之间相互独立,可以同时训练。 串行(Sequential)。各个弱学习器必须串行,后一个模型依赖前一个的结果。
核心使命 降低方差(Variance)。通过平均多个过拟合的模型来消灭过拟合。 降低偏差(Bias)。通过一轮轮纠错,强行提升模型的拟合能力(消灭欠拟合)。
数据抽取 Bootstrap 抽样(有放回的随机抽样),每个模型的样本权重完全一样。 每次使用全量数据,但根据上一轮的预测错误率,动态调整样本的权重或拟合残差
弱学习器特征 倾向于使用强学习器(如长得很深的、容易过拟合的 CART 决策树)。 倾向于使用弱学习器(如只切了一刀的、极易欠拟合的“残差小树桩” Stump)。

一、 Bagging 算法的算法流程(并行架构)

Bagging(Bootstrap Aggregating)的流程核心是“独立、并行、平均分权”。

假设我们的原始数据集为 D,包含 N 个样本,我们要构建一个包含 T 个基模型的 Bagging 集成系统:

核心步骤:

  1. 并行抽样(自举汇聚)

    启动一个循环,独立重复 T 次。每一轮都对原始数据集 D 进行 Bootstrap 抽样(即有放回的随机抽样),每次抽取 N 个样本。

    • 注:因为是有放回的,某些样本会被重复抽到,某些则抽不到。最终会得到 T 个长得互不相同、但规模一样大的子数据集 {D1, D2, ..., DT}
  2. 并行独立训练

    将这 T 个子数据集同时分发出去。并行地训练 T 个基模型(各个模型之间完全闭关锁国,不知道彼此的存在)。最终得到 T 个训练好的强基模型 {f1, f2, ..., fT}

  3. 聚合投票/平均(Aggregating)

    当来了一个新样本 x 需要预测时:

    • 分类任务:让这 T 个基模型同时对 x 进行预测,统计得票数,少数服从多数(Voted),得票最多的类作为最终输出。
    • 回归任务:让这 T 个基模型输出各自的连续值,直接取算术平均值(Averaged),作为最终输出。

二、 Boosting 算法的算法流程(串行架构)

Boosting 的流程核心是“接力、串行、动态纠错”。它不搞平行宇宙,它搞的是一代代版本的迭代演进。

同样面对包含 N 个样本的数据集 D,我们要迭代 T 轮,训练出 T 个基模型进行接力:

核心步骤:

  1. 初始化“新手包”

    • 如果是调整样本权重的流派(如 AdaBoost):给原始数据集里的每个样本都赋予一个相同的初始权重(均为 $\frac{1}{N}$),此时大家是平等的。
    • 如果是拟合残差的流派(如 GBDT):先初始化一个最简单的常数预测值(比如全量标签的平均值),计算出初始的预测误差(残差)
  2. 串行接力循环(迭代 T 轮)

    进入一个严格的前后依赖循环,从 t = 1T

    • t 步训练:根据当前这轮的样本权重分布(或者当前模型留下的残差),训练第 t 个基模型 ft这个基模型被强强要求:必须拼尽全力去拟合眼前的错题/残差
    • 计算本轮话语权:计算这个基模型 ft 在训练集上的表现(如错误率)。表现越好的模型,在最终团队里的发言权重 αt 就会被分配得越大。
    • 动态更新,为下一轮铺路
      • 权重流派:把本轮 ft 做错的样本的权重调高,做对的样本权重调低,重新打包成一份“错题重灾区数据集”喂给下一轮。
      • 残差流派:用真实值减去当前总模型的预测值,算出最新的残差,作为下一轮的目标。
  3. 加权联合表决

    最终预测新样本 x 时,不是简单的民主投票,而是采取带权重的强力组合

    最终的集成模型 F(x) 是这 T 个基模型的加权求和:

    $$F(x) = \sum_{t=1}^{T} \alpha_t f_t(x)$$

    那个话语权 αt 高的“学霸模型”说了算,话语权低的“偏科模型”只起微调辅助作用。

    随机森林算法

    随机森林算法核心流程

    假设我们的原始数据集为 D,包含 N 个样本、共 M 个特征。我们准备构建一个包含 T 棵决策树的随机森林:

    步骤 1:引入“双重随机性”并行建树(核心精髓)

    启动一个并行循环,独立构建 T 棵 CART 决策树。在构建每棵树的过程中,都要注入以下两层随机性

    1. 第一重随机(样本随机)

      利用 Bootstrap 抽样(有放回的随机抽样),从原始的 N 个样本中强行抽取 N 次,形成一个用于训练当前树的子数据集 Dt

      • 注:因为是有放回的,大约会有 36.8% 的样本永远抽不到,这部分数据被称为袋外数据(OOB, Out-of-Bag),天然可以用来做不需要交叉验证的泛化评估。
    2. 第二重随机(特征随机)

      当这棵树在向下分裂节点时,算法不从全部 M 个特征中挑选最优的,而是先随机盲选一部分特征(数量通常为 $m = \sqrt{M}$log2M),然后再从这 m 个随机候选特征中,利用基尼系数(Gini)或平方误差(MSE)选出那个最好的特征进行二叉切分。

    步骤 2:树木无限生长(不剪枝)

    让这 T 棵树在各自的随机宇宙里完全长完,直到每个叶子节点都达到极高的纯度。

    • 底层哲学:因为引入了特征和样本的双重随机性,每棵树各过拟合各的(它们的过拟合噪声是高度不相关的),所以不需要单独对树进行繁琐的剪枝。

    步骤 3:多方会审,聚合预测(Aggregating)

    当森林构建完毕,来了一个全新的测试样本 x 时,所有树木同时开工:

    • 分类任务(民主投票):让 T 棵树对 x 进行分类,统计各个类别的票数,少数服从多数,得票最高的类别即为最终预测结果。
    • 回归任务(算术平均):让 T 棵树输出各自的连续值预测,直接计算这 T 个输出值的算术平均值,作为最终的预测结果。

    Adaboost

    1. 动态调整样本权重(关注错题)

    在每一轮训练中,数据集里的每个样本都有一个权重。

    • 如果某个样本被当前的弱分类器预测错误,它的权重就会在下一轮中被大幅调高,变成“重灾区错题”;
    • 如果样本预测正确,它的权重就会被调低
    • 效果:下一轮的弱分类器被迫把绝大部分精力都放在那些“前人屡屡做错的难题”上。

    2. 动态计算模型话语权(学霸权力大)

    每个弱分类器训练完后,AdaBoost 会根据它在当前数据集上的分类错误率,为它计算一个发言权重(分类器权重 α

    • 错误率越低(表现越好),这个模型的 α 就越大,在最终决议时的话语权就重;
    • 错误率接近 50%(相当于瞎猜),它的 α 就会接近 0,几乎没有话语权。

    3. 加权投票表决(精英联合)

    最终预测时,不是简单的“少数服从多数”,而是“加权投票”。把所有弱分类器的预测结果乘以它们各自的发言权重 α 进行累加,最后看正负号或者总分决定最终类别。

无监督学习:距离度量与 K-means 聚类

KNN(K-Nearest Neighbors,K近邻)

步骤 1:设定超参数 K

在开始之前,我们需要人工指定一个整数 K(比如 K = 3K = 5)。这个 K 代表我们最终要参考多少个“最近的邻居”。

  • 注:如果是二分类任务,K 通常选奇数,防止投票时出现平局。

步骤 2:计算距离(全量大扫除)

算法会遍历训练集中的每一个样本,计算新样本 x 与训练集中各个样本之间的几何距离

  • 在连续特征空间中,最常用的是欧氏距离(Euclidean Distance)

    $$d = \sqrt{\sum_{i=1}^{n} (x_i - y_i)^2}$$

  • 在某些高维或特定业务场景下,也会使用曼哈顿距离闵可夫斯基距离

步骤 3:挑选出最近的 K 个“邻居”

将计算出的所有距离进行从小到大排序,挑选出距离最近(也就是相似度最高)的 K 个训练集样本

步骤 4:投票决议,胜者为王(Aggregating)

统计这 K 个最邻居的标签类别。

  • 分类任务:采用多数表决制(Majority Voting)。这 K 个邻居里哪种类别最多,新样本就归为哪一类(比如 5 个邻居里有 4 个是“猫”,1 个是“狗”,那新样本判定为“猫”)。
  • 回归任务:如果预测的是连续值,则直接计算这 K 个邻居标签值的算术平均值作为最终输出。

K-means(K-均值)聚类

步骤 1:初始化“圈子中心”(随机选种)

在特征空间中,随机挑选 K 个点 作为初始的聚类中心(Centroids),我们把它们记为 {μ1, μ2, ..., μK}

  • 注:最原始的做法是直接从训练集里随机盲抽 K 个样本点作为中心。

步骤 2:对样本进行“划分子集”(E 步:分配身份)

遍历数据集中的每一个样本点 xi,计算它到这 K 个聚类中心的欧氏距离

$$d = \sqrt{\sum (x_{i} - \mu_k)^2}$$

通过对比,把这个样本点分配给距离它最近的那一个聚类中心所在的簇

  • 通俗理解:每个样本点都在特征空间里找离自己最近的“组织”,并加入进去。这一步结束后台面上会诞生 K 个临时的圈子。

步骤 3:重新计算“圈子中心”(M 步:中心漂移)

对于刚刚诞生的这 K 个圈子,分别计算每个圈子内部所有成员特征的算术平均值(均值)

$$\mu_k = \frac{1}{\vert{}C_k\vert{}} \sum_{x \in C_k} x$$

将算出来的这个“几何重心”,作为全新的聚类中心。此时,这 K 个中心点会发生位置的“漂移”。

步骤 4:循环迭代,直到收敛

将更新后的新中心点重新喂回 “步骤 2”,再次让所有人重新找最近的组织分配身份,接着进 “步骤 3” 重新计算中心。

如此反复循环,直到触发以下终止条件之一:

  1. 中心点不再动了:新计算出来的均值中心和上一轮的中心完全重合(或变化小于极小阈值)。
  2. 所有人的身份固化了:连续两轮迭代中,没有任何一个样本点的簇分配发生改变。
  3. 达到了最大设定的迭代步数(防止死循环)。

SVM 深度探究与贝叶斯优化

降维

解释 PCA 算法的原理和步骤

假设我们的原始数据集为 X,包含 n 个样本,每个样本有 m 个特征。即 X 是一个 n × m 的矩阵。我们希望将其降维到 k 维(k < m)。

步骤 1:特征去中心化(中心化处理)

为了消除量纲对均值的影响,必须将每个特征的均值归零。计算每个特征(每一列)的平均值 μj,然后让每个样本的该特征都减去这个均值:

Xnew = X − μ

经过这一步后,数据集的中心点完美平移到了坐标轴的原点 (0, 0)

步骤 2:计算协方差矩阵(Covariance Matrix)

协方差矩阵用来衡量特征与特征之间的相关性。计算中心化后的矩阵 Xnew 的协方差矩阵 Σ

$$\Sigma = \frac{1}{n-1} X_{\text{new}}^T X_{\text{new}}$$

得到的 Σ 是一个 m × m 的对称矩阵。矩阵对角线上的元素是各个特征自己的方差,非对角线上的元素是特征之间的协方差。

步骤 3:特征值分解,求出特征值与特征向量

对协方差矩阵 Σ 进行矩阵特征值分解(Eigendecomposition):

Σv = λv

  • 得到 m特征值 λ1, λ2, ..., λm(代表了新坐标轴方向上的方差大小)。
  • 以及对应的 m特征向量 v1, v2, ..., vm(代表了新坐标轴的空间走向,且彼此正交)。

步骤 4:挑选前 k 个最大特征值对应的特征向量

  1. 将特征值 λ 从大到小进行排序。
  2. 挑选出最大的前 k 个特征值,并取出它们对应的特征向量 [v1, v2, ..., vk]
  3. 把这 k 个列向量纵向拼接,组合成一个投影矩阵(变换矩阵) W,它的维度是 m × k

步骤 5:矩阵相乘,完成降维投影

将去中心化后的原始数据矩阵 Xnew 与投影矩阵 W 进行矩阵乘法,得到降维后的全新数据集 Y

Y = Xnew ⋅ W

由于 Xnew 的维度是 n × mW 的维度是 m × k,相乘后得到的 Y 维度正是 n × k。降维大功告成!