三种决策树总结
1 课程概览
本课总结三种决策树(ID3、C4.5、CART)的对比。包括提出时间、划分标准、数据类型、特点等。重点讲解CART决策树的特点:二叉树、基尼指数、既能分类又能回归。
2 核心概念与定义
- ID3:使用信息增益,偏向取值多的特征。
- C4.5:使用信息增益率,缓解ID3的偏向。
- CART:使用基尼指数,二叉树,既能分类又能回归。
3 算法与模型详解
3.1 三种决策树对比
| 特性 | ID3 | C4.5 | CART |
|---|---|---|---|
| 提出时间 | 最早 | 较晚 | 中间 |
| 划分标准 | 信息增益 | 信息增益率 | 基尼指数 |
| 策略 | 越大越好 | 越大越好 | 越小越好 |
| 数据类型 | 离散 | 离散+连续 | 离散+连续 |
| 任务 | 分类 | 分类 | 分类+回归 |
| 树结构 | 多叉 | 多叉 | 二叉 |
| 大数据集 | 适合 | 不适合 | 适合 |
3.2 划分标准计算
信息增益(ID3): $$g(D, A) = H(D) - H(D|A) = \text{熵} - \text{条件熵}$$
信息增益率(C4.5): $$g_R(D, A) = \frac{g(D, A)}{H_A(D)} = \frac{\text{信息增益}}{\text{特征熵}}$$
基尼指数(CART): $$\text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2$$
$$\text{GiniIndex}(D, A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} \text{Gini}(D_i)$$
3.3 ID3特点
优点:
- 简单易懂
缺点:
- 只能处理离散数据
- 倾向于选择取值多的特征
- 容易过拟合
3.4 C4.5特点
优点:
- 缓解ID3偏向取值多的属性
- 可以处理连续性数值
缺点:
- 只适合驻留于内存的数据集
- 大数据集做不了(需要计算每列的特征熵)
3.5 CART特点
优点:
- 既能分类,又能回归
- 可以处理离散和连续数据
- 采用基尼指数,计算量小
- 必须是二叉树
二叉树处理方式:
- 二分类:直接计算
- 多分类:选择一个作为A类,其余作为B类
- 例如:结婚、单身、离异 → 结婚 vs 其他
- 连续数据:先排序,用中间值作为切割值
3.6 CART二叉树示例
婚姻状况(三分类):
- 结婚、单身、离异
处理方式:
- 结婚 vs 其他(单身+离异)
- 单身 vs 其他(结婚+离异)
- 离异 vs 其他(结婚+单身)
选择基尼指数最小的划分
3.7 特征筛选总结
| 决策树 | 指标 | 策略 |
|---|---|---|
| ID3 | 信息增益 | 越大越好 |
| C4.5 | 信息增益率 | 越大越好 |
| CART | 基尼指数 | 越小越好 |
3.8 选择题解析
题目:下列关于CART树的说法,正确的是?
选项:
- 基尼指数越大越优先选择 ❌(越小越好)
- 基尼指数是CART算法中用于划分属性的重要依据 ✓
- 基尼指数的计算使用到了自然对数 ❌(没有对数)
- CART算法不能用于回归 ❌(既能分类又能回归)
答案:B(选项2)
4 数学原理与推导
4.1 信息增益
$$g(D, A) = H(D) - H(D|A)$$
4.2 信息增益率
$$g_R(D, A) = \frac{g(D, A)}{H_A(D)}$$
4.3 基尼值
$$\text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2$$
4.4 基尼指数
$$\text{GiniIndex}(D, A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} \text{Gini}(D_i)$$
5 代码示例
import numpy as np
# 1. 三种决策树的划分标准计算
def entropy(labels):
"""熵"""
_, counts = np.unique(labels, return_counts=True)
probabilities = counts / len(labels)
return -np.sum(probabilities * np.log2(probabilities))
def conditional_entropy(feature, labels):
"""条件熵"""
unique_values = np.unique(feature)
total = len(labels)
cond_ent = 0
for value in unique_values:
subset = labels[feature == value]
weight = len(subset) / total
cond_ent += weight * entropy(subset)
return cond_ent
def information_gain(feature, labels):
"""信息增益(ID3)"""
return entropy(labels) - conditional_entropy(feature, labels)
def feature_entropy(feature):
"""特征熵"""
return entropy(feature)
def information_gain_ratio(feature, labels):
"""信息增益率(C4.5)"""
ig = information_gain(feature, labels)
fe = feature_entropy(feature)
return ig / fe if fe > 0 else 0
def gini(labels):
"""基尼值"""
_, counts = np.unique(labels, return_counts=True)
probabilities = counts / len(labels)
return 1 - np.sum(probabilities ** 2)
def gini_index(feature, labels):
"""基尼指数(CART)"""
unique_values = np.unique(feature)
total = len(labels)
gi = 0
for value in unique_values:
subset = labels[feature == value]
weight = len(subset) / total
gi += weight * gini(subset)
return gi
# 2. 示例数据
labels = np.array(['A', 'A', 'A', 'B', 'B', 'B'])
feature = np.array(['alpha', 'alpha', 'alpha', 'alpha', 'beta', 'beta'])
# 3. 计算三种指标
print("=== 三种决策树划分标准 ===")
ig = information_gain(feature, labels)
igr = information_gain_ratio(feature, labels)
gi = gini_index(feature, labels)
print(f"ID3 - 信息增益: {ig:.4f} (越大越好)")
print(f"C4.5 - 信息增益率: {igr:.4f} (越大越好)")
print(f"CART - 基尼指数: {gi:.4f} (越小越好)")
# 4. 基尼值示例
print("\n=== 基尼值示例 ===")
datasets = {
'10个红球': np.array(['红'] * 10),
'5红5蓝': np.array(['红'] * 5 + ['蓝'] * 5),
'4红3蓝3绿': np.array(['红'] * 4 + ['蓝'] * 3 + ['绿'] * 3),
'10个不同类': np.array([str(i) for i in range(10)])
}
for name, data in datasets.items():
g = gini(data)
print(f"{name}: 基尼值 = {g:.4f}")
# 5. CART二叉树处理多分类
print("\n=== CART二叉树处理多分类 ===")
# 婚姻状况:结婚、单身、离异
labels_multi = np.array(['结婚', '结婚', '单身', '单身', '离异', '离异'])
feature_multi = np.array(['A', 'A', 'B', 'B', 'C', 'C'])
# 三种二分类方式
splits = [
('结婚 vs 其他', np.array([1, 1, 0, 0, 0, 0])),
('单身 vs 其他', np.array([0, 0, 1, 1, 0, 0])),
('离异 vs 其他', np.array([0, 0, 0, 0, 1, 1]))
]
for name, split in splits:
gi = gini_index(split, labels_multi)
print(f"{name}: 基尼指数 = {gi:.4f}")
# 6. 三种决策树特点总结
print("\n=== 三种决策树特点总结 ===")
print("ID3:")
print(" - 划分标准: 信息增益 (越大越好)")
print(" - 数据类型: 离散")
print(" - 缺点: 偏向取值多的特征")
print("\nC4.5:")
print(" - 划分标准: 信息增益率 (越大越好)")
print(" - 数据类型: 离散+连续")
print(" - 缺点: 不适合大数据集")
print("\nCART:")
print(" - 划分标准: 基尼指数 (越小越好)")
print(" - 数据类型: 离散+连续")
print(" - 任务: 分类+回归")
print(" - 特点: 二叉树")
输出示例:
=== 三种决策树划分标准 ===
ID3 - 信息增益: 0.4591 (越大越好)
C4.5 - 信息增益率: 0.5000 (越大越好)
CART - 基尼指数: 0.1667 (越小越好)
=== 基尼值示例 ===
10个红球: 基尼值 = 0.0000
5红5蓝: 基尼值 = 0.5000
4红3蓝3绿: 基尼值 = 0.6600
10个不同类: 基尼值 = 0.9000
=== CART二叉树处理多分类 ===
结婚 vs 其他: 基尼指数 = 0.4444
单身 vs 其他: 基尼指数 = 0.4444
离异 vs 其他: 基尼指数 = 0.4444
=== 三种决策树特点总结 ===
ID3:
- 划分标准: 信息增益 (越大越好)
- 数据类型: 离散
- 缺点: 偏向取值多的特征
C4.5:
- 划分标准: 信息增益率 (越大越好)
- 数据类型: 离散+连续
- 缺点: 不适合大数据集
CART:
- 划分标准: 基尼指数 (越小越好)
- 数据类型: 离散+连续
- 任务: 分类+回归
- 特点: 二叉树
6 重难点与易错提醒
- ❗重点:ID3用信息增益,C4.5用信息增益率,CART用基尼指数。
- ❗重点:ID3/C4.5越大越好,CART越小越好。
- ❗重点:CART必须是二叉树。
- ❗重点:CART既能分类又能回归。
- ❗重点:基尼指数计算没有对数,计算量小。
- ⚠️易错:混淆三种决策树的策略方向。
- ⚠️易错:CART多分类需要转换为二分类。
- 💡深入理解:CART通过二叉树结构简化了计算。
7 课堂问答精选
Q: 三种决策树有什么区别?
A:
- ID3:信息增益(越大越好),只能处理离散数据,偏向取值多的特征
- C4.5:信息增益率(越大越好),能处理连续数据,不适合大数据集
- CART:基尼指数(越小越好),能处理离散和连续数据,既能分类又能回归,必须是二叉树
Q: CART如何处理多分类问题?
A: CART必须是二叉树,处理多分类时需要转换为二分类。例如婚姻状况有结婚、单身、离异三类,可以转换为:
- 结婚 vs 其他(单身+离异)
- 单身 vs 其他(结婚+离异)
- 离异 vs 其他(结婚+单身) 选择基尼指数最小的划分方式。
8 本课小结
- ID3:信息增益,越大越好,离散数据。
- C4.5:信息增益率,越大越好,离散+连续。
- CART:基尼指数,越小越好,二叉树,分类+回归。
- CART特点:计算量小,二叉树,多分类转二分类。
9 延伸思考与实践
- 实践:比较三种决策树的划分标准。
- 预习:CART案例(泰坦尼克号)。
- 思考:为什么CART必须是二叉树?