C4.5树之信息增益率
1 课程概览
本课讲解C4.5决策树,基于ID3的优化。ID3偏向选择特征种类多的特征,容易导致过拟合。C4.5使用信息增益率(信息增益/特征熵)解决此问题。特征熵作为惩罚系数,特征取值越多,惩罚越大。
2 核心概念与定义
- C4.5决策树:基于ID3优化,使用信息增益率划分节点。
- 信息增益率:信息增益 / 特征熵。
- 特征熵:惩罚系数,特征取值越多,特征熵越大。
- 惩罚系数:特征熵的倒数,特征熵越大,惩罚系数越小。
3 算法与模型详解
3.1 ID3的不足
问题:偏向选择特征种类多的特征
原因:
- 特征划分的种类越多 → 信息增益越大
- 信息增益越大 → 越优先考虑
- 容易导致过拟合
示例:
- 特征A:取值少
- 特征B:取值多
- B的信息增益更大 → B作为根节点
过拟合原因:
- 整棵树过于依赖少数特征
- 只根据少数特征进行学习
- 容易学到脏数据(如天鹅都是白色的)
3.2 C4.5解决方案
方法:使用信息增益率
公式: $$\text{信息增益率} = \frac{\text{信息增益}}{\text{特征熵}} = \text{信息增益} \times \frac{1}{\text{特征熵}}$$
惩罚系数:特征熵的倒数
特点:
- 特征熵越大 → 惩罚系数越小
- 特征熵越小 → 惩罚系数越大
- 对信息增益进行修正
3.3 特征熵计算
定义:把特征列当做标签计算的熵
公式: $$H_A(D) = -\sum_{i=1}^{n} \frac{|A_i|}{|D|} \log_2 \frac{|A_i|}{|D|}$$
说明:与分类占比 × log2(分类占比) 的计算方式相同
3.4 信息增益率本质
本质:特征的信息增益 / 特征的内在信息
理解:
- 信息增益:特征对分类的贡献
- 特征熵(内在信息):特征本身的复杂度
- 信息增益率:对信息增益进行修正,增加乘法系数
3.5 特征取值个数的影响
| 特征取值个数 | 信息增益 | 特征熵 | 惩罚系数 | 信息增益率 |
|---|---|---|---|---|
| 多 | 大 | 大 | 小 | 适中 |
| 少 | 小 | 小 | 大 | 适中 |
结论:
- 特征取值越多 → 信息增益越大,但特征熵也越大
- 特征熵越大 → 惩罚系数越小
- 信息增益率平衡了两者
3.6 ID3 vs C4.5
| 对比 | ID3 | C4.5 |
|---|---|---|
| 划分标准 | 信息增益 | 信息增益率 |
| 偏向 | 取值多的特征 | 平衡 |
| 过拟合 | 容易 | 较少 |
| 公式 | g(D,A) | g(D,A)/H_A(D) |
4 数学原理与推导
4.1 信息增益
$$g(D, A) = H(D) - H(D|A)$$
4.2 特征熵
$$H_A(D) = -\sum_{i=1}^{n} \frac{|A_i|}{|D|} \log_2 \frac{|A_i|}{|D|}$$
4.3 信息增益率
$$g_R(D, A) = \frac{g(D, A)}{H_A(D)}$$
4.4 惩罚系数
$$\text{惩罚系数} = \frac{1}{H_A(D)}$$
特点:
- $H_A(D)$ 越大 → 惩罚系数越小
- $H_A(D)$ 越小 → 惩罚系数越大
5 代码示例
import numpy as np
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):
"""计算信息增益"""
return entropy(labels) - conditional_entropy(feature, labels)
def feature_entropy(feature):
"""计算特征熵(把特征列当做标签)"""
return entropy(feature)
def information_gain_ratio(feature, labels):
"""计算信息增益率"""
ig = information_gain(feature, labels)
fe = feature_entropy(feature)
return ig / fe if fe > 0 else 0
# 1. 模拟ID3偏向多值特征的问题
print("=== ID3偏向多值特征的问题 ===")
labels = np.array(['A', 'A', 'B', 'B', 'A', 'B'])
# 特征B:取值多(6个不同值)
feature_many = np.array(['a', 'b', 'c', 'd', 'e', 'f'])
# 特征A:取值少(2个不同值)
feature_few = np.array(['x', 'x', 'x', 'y', 'y', 'y'])
ig_many = information_gain(feature_many, labels)
ig_few = information_gain(feature_few, labels)
print(f"多值特征 - 信息增益: {ig_many:.4f}")
print(f"少值特征 - 信息增益: {ig_few:.4f}")
print(f"ID3会选择: 多值特征(信息增益大)")
# 2. C4.5的解决方案
print("\n=== C4.5的解决方案 ===")
fe_many = feature_entropy(feature_many)
fe_few = feature_entropy(feature_few)
igr_many = information_gain_ratio(feature_many, labels)
igr_few = information_gain_ratio(feature_few, labels)
print(f"多值特征 - 特征熵: {fe_many:.4f}, 信息增益率: {igr_many:.4f}")
print(f"少值特征 - 特征熵: {fe_few:.4f}, 信息增益率: {igr_few:.4f}")
print(f"C4.5会选择: 信息增益率大的特征")
# 3. 惩罚系数分析
print("\n=== 惩罚系数分析 ===")
penalty_many = 1 / fe_many if fe_many > 0 else 0
penalty_few = 1 / fe_few if fe_few > 0 else 0
print(f"多值特征 - 特征熵: {fe_many:.4f}, 惩罚系数: {penalty_many:.4f}")
print(f"少值特征 - 特征熵: {fe_few:.4f}, 惩罚系数: {penalty_few:.4f}")
print("特征熵越大 → 惩罚系数越小")
# 4. 完整计算示例
print("\n=== 完整计算示例 ===")
# 6个样本,3个A,3个B
labels = np.array(['A', 'A', 'A', 'B', 'B', 'B'])
# 特征:4个alpha,2个beta
feature = np.array(['alpha', 'alpha', 'alpha', 'alpha', 'beta', 'beta'])
print(f"数据: labels={labels}")
print(f"特征: feature={feature}")
ent = entropy(labels)
cond_ent = conditional_entropy(feature, labels)
ig = information_gain(feature, labels)
fe = feature_entropy(feature)
igr = information_gain_ratio(feature, labels)
print(f"\n1. 熵 H(D): {ent:.4f}")
print(f"2. 条件熵 H(D|A): {cond_ent:.4f}")
print(f"3. 信息增益 g(D,A): {ig:.4f}")
print(f"4. 特征熵 H_A(D): {fe:.4f}")
print(f"5. 信息增益率 g_R(D,A): {igr:.4f}")
print(f"6. 惩罚系数: {1/fe:.4f}")
输出示例:
=== ID3偏向多值特征的问题 ===
多值特征 - 信息增益: 1.0000
少值特征 - 信息增益: 0.0817
ID3会选择: 多值特征(信息增益大)
=== C4.5的解决方案 ===
多值特征 - 特征熵: 2.5850, 信息增益率: 0.3868
少值特征 - 特征熵: 1.0000, 信息增益率: 0.0817
C4.5会选择: 信息增益率大的特征
=== 惩罚系数分析 ===
多值特征 - 特征熵: 2.5850, 惩罚系数: 0.3868
少值特征 - 特征熵: 1.0000, 惩罚系数: 1.0000
特征熵越大 → 惩罚系数越小
=== 完整计算示例 ===
数据: labels=['A' 'A' 'A' 'B' 'B' 'B']
特征: feature=['alpha' 'alpha' 'alpha' 'alpha' 'beta' 'beta']
1. 熵 H(D): 1.0000
2. 条件熵 H(D|A): 0.5409
3. 信息增益 g(D,A): 0.4591
4. 特征熵 H_A(D): 0.9183
5. 信息增益率 g_R(D,A): 0.5000
6. 惩罚系数: 1.0890
6 重难点与易错提醒
- ❗重点:C4.5使用信息增益率划分节点。
- ❗重点:信息增益率 = 信息增益 / 特征熵。
- ❗重点:特征熵是惩罚系数,特征取值越多,特征熵越大。
- ❗重点:特征熵越大,惩罚系数越小。
- ❗重点:C4.5解决ID3偏向多值特征的问题。
- ⚠️易错:混淆信息增益和信息增益率。
- ⚠️易错:特征熵的计算(把特征列当做标签)。
- 💡深入理解:C4.5通过惩罚系数平衡了信息增益的偏向。
7 课堂问答精选
Q: C4.5如何解决ID3的缺点?
A: ID3偏向选择特征种类多的特征(取值越多,信息增益越大)。C4.5使用信息增益率 = 信息增益 / 特征熵。特征熵作为惩罚系数,特征取值越多,特征熵越大,惩罚系数越小,从而避免偏向取值较多的特征。
Q: 什么是特征熵?
A: 特征熵是把特征列当做标签计算的熵。计算方式与普通熵相同,只是把特征列的值当做标签。特征取值越多,特征熵越大。特征熵在C4.5中作为惩罚系数的倒数,用于修正信息增益的偏向。
8 本课小结
- ID3缺点:偏向选择特征种类多的特征。
- C4.5:使用信息增益率划分节点。
- 信息增益率 = 信息增益 / 特征熵。
- 特征熵:把特征列当做标签计算的熵。
- 惩罚系数:特征熵的倒数,特征熵越大,惩罚系数越小。
9 延伸思考与实践
- 实践:用Python计算信息增益率。
- 预习:Cart树原理介绍。
- 思考:为什么C4.5能解决过拟合问题?