**两个关键概念**:
#第一性原理
- 信息熵: 想象你有一个装满不同颜色小球的罐子。如果所有球都是一个颜色,那么闭着眼睛拿球时你很容易猜对颜色,这种情况的"信息熵"很低。但如果每种颜色的球数量相等,你就很难猜对,这种情况的"信息熵"就高。
- **都穿校服**:大家衣服都一样,分类很纯粹,没有什么不确定性,所以熵比较小。
- **夜店各种服装**:服饰类型五花八门、混杂度高,不确定性大,所以熵值更高。
- 信息增益: 继续用猜动物的例子。问"这个动物会飞吗?"比问"这个动物喜欢吃胡萝卜吗?"可能更有助于你猜对。前一个问题带来的信息增益更大。
- 问"纹身吗"比问"喜欢吃馒头吗"更可能有助于判断是不是一个好女孩,前一个问题带来的信息增益更大。
- 所以决策树的可解释性会更好
**核心思想**是一个**贪心构建过程**:
- 从根节点开始,选一个在当前数据子集上"最能区分样本"的特征及分裂点。比如使用特征 Age 分裂后,**数据整体的熵减少了多少**。减少得越多,说明分裂越有效,让子节点变得更"纯"(不确定性更低),因此信息增益就越大。
- 将数据子集分裂为若干个子集后,再对子集递归地做同样的分裂选择。
- 一直分裂,直到满足终止条件(如达到最大深度、节点纯度足够高、样本数不足等)。
典型的分裂指标:
1. **信息增益**(基于熵)
$\text{InfoGain} = H(\text{parent}) - \sum_{k} \frac{N_k}{N} H(\text{child}_k)$,
- 其中 $H(\cdot)$ 是熵,$\frac{N_k}{N}$ 表示子节点占父节点数据量的比例。
- 直观理解就是"分裂前后的熵之差",越大说明"分裂后越纯",效果越好。
2. **Gini指数**(CART 决策树)
$Gini(D) = \sum_{i=1}^{C} p_i (1 - p_i)$,
- 其中 $p_i$ 是某类在数据集 $D$ 中的比例。
- 分裂时,会计算分裂前、后的加权 Gini,**Gini 越小越纯**。
停止分裂 & 剪枝
- 如果过度分裂,树会过拟合(非常深的树可能把训练数据划分到每叶节点只有1个样本),导致泛化能力差。
- 因此需要设置**最大深度**、**最小叶子样本数**、**最小信息增益阈值**等超参数来阻止过度生长;或者先让树长到较深,再使用**剪枝**(pruning)技术,如"代价复杂度剪枝(CCP)"等,把贡献不大的分支剪掉。
- 这对应神经网络里的**正则化**(如 L2、L1、Dropout)——决策树也需要**限制模型复杂度**,以减少过拟合风险。
## 数据集
假设我们想预测某人 "是否会购买 X 产品(Buys?)",数据如下:
| **Age** | **Student?** | **Income** | | **Buys?** |
|:-----: |:----------: |:--------: | --- |:-------: |
| Young | Yes | Low | - | Yes |
| Young | No | High | - | No |
| Mid | Yes | High | - | Yes |
- **Age**: 取值有 "Young" 或 "Mid"(在更大数据里可能还有 "Old" 等,这里只出现了两种)
- **Student?**: 是否是学生 (Yes/No)
- **Income**: 这里只出现 "Low" 或 "High"
- **Buys?**: 最终分类标签 (Yes/No)
我们要构建一棵**分类决策树**,用特征 (Age, Student?, Income) 来预测标签 (Buys?)。
---
## 第 1 步:计算数据集的整体熵
在 ID3 算法里,需要先计算**当前数据集的熵**(Entropy)。熵衡量"混杂度"或"不确定性",分类越混乱,熵越高。
### 1.1 统计各类样本数
- "Yes" 样本数: 2 条(第 1 行、第 3 行)
- "No" 样本数: 1 条(第 2 行)
总样本数 N=3N = 3。
### 1.2 计算熵
$H(S) \;=\; - \sum_{c \in \{\text{Yes},\text{No}\}} p(c)\,\log_2\,p(c)$
这里
- $p(\text{Yes}) = \tfrac{2}{3}$
- $p(\text{No}) = \tfrac{1}{3}$
因此
$H(S) = - \Bigl(\frac{2}{3}\log_2 \frac{2}{3} + \frac{1}{3}\log_2 \frac{1}{3}\Bigr)$.
可以用大约数值估计(只要看个相对大小就行):
- $\log_2 \tfrac{2}{3}\approx -0.585$
- $\log_2 \tfrac{1}{3}\approx -1.585$
所以
$H(S) \approx -\Bigl(\frac{2}{3}\times(-0.585) + \frac{1}{3}\times(-1.585)\Bigr) = -\Bigl(-\,0.39 + -\,0.53\Bigr) = 0.92 \;\;(\text{约值})$
这里结果不必特别精确,你只要知道它介于 0 和 1.58(=$\log_2(3)$)之间即可。**熵越大表示"越混杂"**。
## 第 2 步:分别尝试用各特征分裂,看哪个信息增益最大
ID3 算法会**遍历所有特征**(Age, Student?, Income),看看以该特征做"根节点分裂"后,数据集的熵降低了多少(也就是**信息增益**)。信息增益越大,说明这个特征"分裂"效果越好,更能把数据切分得纯净。
### 2.1 以特征 Age 分裂
- **Age = Young**: 含第 1、2 行,共 2 条
- 其中标签 "Yes" 1 条,"No" 1 条 ⇒ 这个子集还是混杂;熵可计算。
- **Age = Mid**: 含第 3 行,共 1 条
- 其中标签 "Yes" 1 条 ⇒ 这是纯集,熵=0
#### 2.1.1 计算子集熵
1. 子集 "Age=Young" 有 2 个样本: (Yes=1, No=1)
$H(\text{Young}) = - \bigl(\tfrac{1}{2}\log_2 \tfrac{1}{2} + \tfrac{1}{2}\log_2 \tfrac{1}{2}\bigr) = 1.$
1. 子集 "Age=Mid" 有 1 个样本: (Yes=1, No=0),这是纯集
$H(\text{Mid}) = 0.$
#### 2.1.2 加权求和(分裂后的熵)
分裂后数据被分成 2 个子集(Young, Mid),它们的大小分别是 2、1,总共 3 个样本:
$H_{\text{Age}} = \frac{2}{3} \times 1 + \frac{1}{3} \times 0 = \frac{2}{3}.$
#### 2.1.3 信息增益
$\text{InfoGain}(\text{Age}) = H(S) - H_{\text{Age}} \approx 0.92 - \frac{2}{3} = 0.92 - 0.67 = 0.25.$
(大约值)
---
### 2.2 以特征 Student? 分裂
- **Student = Yes**: 第 1、3 行,共 2 条
- 标签情况: (Yes=2, No=0) 纯集
- **Student = No**: 第 2 行,共 1 条
- 标签情况: (Yes=0, No=1) 纯集
#### 2.2.1 子集熵
1. 子集 "Student=Yes": 2 个样本,都是 Yes ⇒ 纯集,熵 = 0
2. 子集 "Student=No": 1 个样本,都是 No ⇒ 纯集,熵 = 0
#### 2.2.2 加权求和(分裂后的熵)
$H_{\text{Student}} = \frac{2}{3} \times 0 + \frac{1}{3} \times 0 = 0.$
#### 2.2.3 信息增益
$\text{InfoGain}(\text{Student}) = H(S) - H_{\text{Student}} = 0.92 - 0 = 0.92.$
这很高,说明 Student? 非常能区分数据。
---
### 2.3 以特征 Income 分裂
- **Income = Low**: 第 1 行,共 1 条 => (Yes=1)
- **Income = High**: 第 2、3 行,共 2 条 => (Yes=1, No=1)
#### 2.3.1 子集熵
1. "Income=Low" => 1 条 Yes => 纯集,熵 = 0
2. "Income=High" => 2 条(Yes=1, No=1),熵 = 1
#### 2.3.2 加权求和
$H_{\text{Income}} = \frac{1}{3}\times 0 + \frac{2}{3}\times 1 = \frac{2}{3}.$
#### 2.3.3 信息增益
$\text{InfoGain}(\text{Income}) = H(S) - H_{\text{Income}} = 0.92 - 0.67 = 0.25.$
## 第 3 步:选信息增益最大的特征做根节点
比较三者:
- $\text{InfoGain}(Age) \approx 0.25$
- $\text{InfoGain}(Student) = 0.92$
- $\text{InfoGain}(Income) \approx 0.25$
可见 **Student?** 的信息增益最高,所以 **ID3** 会选择 **Student?** 作为**根节点**来分裂。
---
## 第 4 步:根据 Student? 分裂数据
- **Student = Yes** => 子集 { (Young, Yes, Low, Yes), (Mid, Yes, High, Yes) }
- 这两个样本标签全是 "Yes",是**纯集**;无需继续分裂
- **Student = No** => 子集 { (Young, No, High, No) }
- 这 1 个样本标签是 "No",也是纯集;无需继续分裂
因为在根节点分裂之后,左右子集都已经纯净,没有混杂,所以**决策树构建完成**。
---
## 第 5 步:得到最终的决策树
画成一棵非常简单的树:
```Java
┌─── Student? ───┐
│ │
(Yes) │ │ (No)
▼ ▼
全部 Yes 全部 No
```
- 如果样本 "Student = Yes",则直接预测标签 "Yes"
- 如果样本 "Student = No",则直接预测标签 "No"
这么简单的树,就能完美地分类这 3 条数据。
---
## 验证或预测新样本
假设来一个新样本 (Age=Young,Student=Yes,Income=High)(Age=Young, Student=Yes, Income=High),我们只需看它的 **Student** 值:
- 它是 "Yes",因此决策树输出 "Yes"。
在这个小数据上非常直接。真实应用中会有更多特征和更多层分裂,但过程类似:**递归地贪心选择分裂特征**,直到子集纯或达到停止条件(如最大深度、最少样本数等)。
---
## 总结
1. **熵与信息增益**:ID3 算法用信息增益来选择分裂特征。谁能最大幅度降低数据的熵,就选谁做节点。
2. **一步步分裂**:在本例中,最初数据的熵约 0.92,用特征 "Student?" 分裂后直接降为 0,这说明它能很好地区分所有样本。
3. **生成树**:最后得到一颗只有一个分裂节点(根节点)的非常小的树:
- "Student=Yes" => 叶子输出 "Yes"
- "Student=No" => 叶子输出 "No"
4. **对新数据的预测**:从根节点判断特征,走向对应叶子,输出标签。
这就是一个**极小的决策树构造示例**,通过这个过程你就能看到——和多层感知机用"梯度下降"优化权重不同,**决策树是用"特征分裂"+"信息增益"**的方式递归构建出来的。本质上都在最小化混杂度/误差,只是实现机制不同。
## 决策树
决策树(Decision Tree)是一种**基于树结构**的模型,用于处理分类或回归问题。它通过对特征进行一系列条件判断(如"特征 A ≤ 某个值?"、"某个类别特征是否等于 X?"等),将样本逐步分到不同子节点,直到到达叶子节点并给出预测结果。
和多层感知机(MLP)中神经元加权求和 + 激活函数不同,**决策树是"离散式"地划分特征空间**:
- 每个节点对应一个**条件判断**
- 若满足条件就往左(或右)子树走,不满足就往另一个子树走
- 最终在叶子节点输出一个预测值(类别/回归值)
下面分步骤介绍决策树的"前向(预测)过程"和"训练(构造树)过程",以及在实际应用中需要注意的要点。
---
## 1. 前向传播(预测)类比
在神经网络(MLP)中,**前向传播**指的是:
- 把输入 xx 乘以权重矩阵、加偏置,再经过激活函数,层层传播,得到输出。
在决策树中,**预测过程**可以类比为一次"**从根节点到叶子节点的传递**":
1. **从根节点开始**
- 根节点上存放了一个"分裂规则"(比如:$\text{Age} \le 30$?$\text{Income} \le 5000$?某特征是否等于某值?等等),拿输入样本在这里判断。
2. **根据特征值,走向左右子树**
- 如果满足节点的分裂条件,就走左子树;否则走右子树(或者根据类比,可能还有多叉分裂的情况)。
3. **重复判断**
- 每到一个子节点,又会有新的分裂条件,继续判断、分支。
4. **到达叶子节点**
- 叶子节点对应一个输出值(对于分类是一个类别标签或类别概率;对于回归是一个实数值)。
- 这就是决策树的最终预测结果。
这一串操作"从根到叶"就好比神经网络里"从输入层到输出层",只是**决策树的计算是基于"判断条件"来走分支**,没有连续可微的"加权求和"操作。
---
## 2. 决策树训练(构造树)
### 2.1 类比"反向传播"?
在[[多层感知机 MLP]]中,"反向传播"通过计算梯度来更新每个权重,最终最小化损失函数。而在决策树里**没有权重矩阵和激活函数**,它的"训练"是**构建出一个合适的分裂结构**(哪个特征先分裂?阈值多少?分裂到什么深度?)。
---
## 3. 损失函数与决策树
在神经网络中,我们显式地设定损失函数(比如 MSE、交叉熵),然后通过反向传播去更新权重。而决策树中,**分类树**常用的信息增益、Gini 指数等"纯度指标"来指导分裂,这些指标本身就充当了"局部的损失函数"。**回归树**则可以显式使用 MSE、MAE 等指标来选择最优分裂点。
也可以把决策树看成是在**局部**(每次分裂)最小化损失——比起神经网络的全局梯度下降,决策树的贪心策略没有**端到端**的"反向传播",但也是一个**以损失(或纯度)为优化目标**的过程。
---
## 4. 举个小例子
来个简化版本,帮助你直观感受决策树的构建:
1. **数据集**
- 如下表,每行有特征 (年龄, 是否有房, 信用等级...),以及标签 (是否违约)。
- 我们要构造一棵分类树来预测"是否违约"。
2. **根节点选择分裂特征**
- 先尝试用"年龄"来分,看看分裂前后的信息增益;再尝试用"是否有房"来分;再尝试用"信用等级"等。
- 计算哪一个分裂带来的信息增益(或 Gini 降低)最大,就选它作为第一步。
3. **生成左右子节点**
- 将数据根据所选特征的分裂规则(如"年龄 ≤ 30 岁" vs "> 30 岁")划分为两部分。
- 然后在每个子节点重复类似操作:继续选分裂特征、划分子节点……直到满足停止条件。
4. **叶子节点**
- 最终可能出现:
- 叶子 A:绝大多数样本是"违约",模型就输出"违约"
- 叶子 B:绝大多数样本是"非违约",模型就输出"非违约"
- 这样就完成了一棵可用于预测的新树。
---
## 5. 使用决策树的实践要点
1. **选择合适的分裂准则**
- **分类**:常见用 Gini 或信息增益。
- **回归**:常见用 MSE、MAE 等。
2. **预剪枝/后剪枝**
- 通过超参数(如 `max_depth`, `min_samples_split`, `min_samples_leaf`, `min_impurity_decrease`)限制树的增长,避免过拟合。
3. **特征类型**
- 对于离散分类特征或连续数值特征,要采用对应的最优分裂策略。
4. **可解释性**
- 决策树可以可视化,直观显示"每一步怎么分裂、为什么这样分裂",这是它的优势。
5. **易受训练数据影响**
- 树对小规模数据或高维数据可能过拟合,或对噪声特征过度分裂;要注意数据清洗、特征选择等。
---
## 6. 类比多层感知机的"训练-预测"流程
可以把决策树的流程也画成一个类似的"训练-预测"图表:
**预测阶段**(相当于 MLP 的"前向传播"):
1. 对新样本从根节点开始,顺着特征条件判断,落到对应叶子。
2. 叶子里的结果(多数投票或均值等)就是预测值。
---
## 7. 小结
- **决策树**是一种"**基于条件分裂**"的模型,和神经网络里的"连续可微计算图"不同。
- 它通过在训练阶段"**贪心地选择分裂特征**,逐层划分",最终得到一棵可对样本进行预测的树结构。
- 训练中使用**信息增益/Gini/MSE**等分裂准则来衡量"分裂效果"并决定如何分裂。
- 过深的树容易过拟合,需要通过**剪枝**或限制深度等方式进行正则化。
- 预测时只需做一串**条件判断**(从根到叶),可视化也比较容易,这使得决策树往往很**易解释**。
---
## 结语
至此,你可以把**决策树**和**多层感知机(MLP)**做一个整体对比:
|指标|多层感知机 (MLP)|决策树 (Decision Tree)|
|:--|:--|:--|
|**模型结构**|多层感知(全连接层 + 激活函数),通过权重和偏置进行线性变换与非线性激活|树形结构,每个节点基于特征做离散分裂,叶子节点最终给出分类/回归值|
|**前向传播**|矩阵乘法 + 激活函数|条件判断,从根节点按特征值分支到叶子|
|**训练方式**|梯度下降+反向传播更新权重|递归选择分裂特征点(贪心),根据信息增益/Gini/MSE 等指标做最优切分|
|**正则化**|权重衰减(L2/L1)、Dropout、BatchNorm 等|剪枝、限制深度、最小样本数、最小增益阈值等|
|**优点**|能拟合复杂函数(深度网络),表达能力强|结构直观,可解释性好,适合很多表格型特征;训练/预测都较快|
|**缺点**|训练需要大量数据,容易过拟合(需要大量正则化技巧)|易受样本噪声影响(不稳定),容易过拟合(需要剪枝等措施),单棵树泛化性能相对有限|
|**延伸**|CNN、RNN、Transformer 等深度网络|随机森林(RF)、梯度提升树(GBDT)、XGBoost、LightGBM 等,都是基于决策树的集成算法|
如果你之后想学习**集成方法**(如随机森林、XGBoost),你就会看到,它们都是在"决策树"的基础上做了**很多改进**或**集成策略**(比如对多棵树取平均、加权等)。
这正如深度学习里,从最简单的 MLP 不断扩展到 CNN、RNN、Transformers 一样,都在核心思想之上演变而来。
---
希望这个分步骤的介绍能让你**像理解 MLP 一样**,快速理解决策树模型的本质。
祝学习顺利!