ID3决策树搭建
1 课程概览
本课通过论坛客户流失数据案例演示ID3决策树的搭建流程。核心思想是优先参考信息增益大的特征列充当节点。分别计算性别和活跃度的信息增益,信息增益大的作为根节点。
2 核心概念与定义
- ID3决策树:根据信息增益划分节点的决策树。
- 核心思想:优先参考信息增益大的特征列充当上层节点。
- 根节点:决策树的起始节点。
- 子集:根据特征划分后的数据子集。
3 算法与模型详解
3.1 ID3决策树构建流程
核心思想:优先参考信息增益大的特征列充当节点
构建步骤:
- 计算每个特征的信息增益
- 信息增益大的特征作为根节点
- 拆分子集
- 对剩余特征继续计算信息增益
- 信息增益大的作为第二层、第三层、第四层节点
- 以此类推
3.2 案例分析
数据:论坛客户流失数据
特征:
- gender(性别)
- Activity_info(活跃度)
标签:是否流失
需求:考察性别和活跃度哪一个对流失率的影响更大
3.3 分析流程
思路:
- 分别计算性别和活跃度的信息增益
- 信息增益大的作为根节点
- 以此类推
步骤:
- 计算信息熵H(D)
- 计算性别的条件熵H(D|gender)
- 计算性别的信息增益g(D, gender)
- 计算活跃度的条件熵H(D|Activity_info)
- 计算活跃度的信息增益g(D, Activity_info)
- 比较两个信息增益,大的作为根节点
3.4 计算过程
步骤1:计算信息熵
信息熵只看标签(是否流失),与特征无关
步骤2:计算各特征的信息增益
对每个特征:
- 按特征值分组
- 计算每组的熵
- 加权求和得到条件熵
- 信息增益 = 信息熵 - 条件熵
步骤3:比较信息增益
- 性别的信息增益
- 活跃度的信息增益
结果:活跃度的信息增益更大,作为根节点
3.5 决策树结构
活跃度(根节点)
├── 高活跃 → ...
├── 中活跃 → 性别
│ ├── 男 → ...
│ └── 女 → ...
└── 低活跃 → ...
4 数学原理与推导
4.1 信息熵
$$H(D) = -\sum_{k=1}^{K} p_k \log_2 p_k$$
4.2 条件熵
$$H(D|A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} H(D_i)$$
4.3 信息增益
$$g(D, A) = H(D) - H(D|A)$$
5 代码示例
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text
from sklearn.preprocessing import LabelEncoder
# 1. 准备数据(论坛客户流失数据)
data = {
'gender': ['男', '女', '男', '女', '男', '女', '男', '女', '男', '女'],
'Activity_info': ['高', '中', '低', '高', '中', '低', '高', '中', '低', '高'],
'churn': ['否', '否', '是', '否', '是', '是', '否', '是', '是', '否']
}
df = pd.DataFrame(data)
print("=== 原始数据 ===")
print(df)
# 2. 计算信息熵
def entropy(labels):
"""计算信息熵"""
_, counts = np.unique(labels, return_counts=True)
probabilities = counts / len(labels)
return -np.sum(probabilities * np.log2(probabilities))
# 3. 计算条件熵
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
# 4. 计算信息增益
def information_gain(feature, labels):
"""计算信息增益"""
return entropy(labels) - conditional_entropy(feature, labels)
# 5. 计算各特征的信息增益
labels = df['churn'].values
print(f"\n=== 信息熵 ===")
print(f"H(D) = {entropy(labels):.4f}")
print(f"\n=== 各特征的信息增益 ===")
for feature_name in ['gender', 'Activity_info']:
feature = df[feature_name].values
ig = information_gain(feature, labels)
print(f"{feature_name}: 信息增益 = {ig:.4f}")
# 6. 构建ID3决策树
# 编码
le_gender = LabelEncoder()
le_activity = LabelEncoder()
le_churn = LabelEncoder()
X = np.column_stack([
le_gender.fit_transform(df['gender']),
le_activity.fit_transform(df['Activity_info'])
])
y = le_churn.fit_transform(df['churn'])
# 创建决策树(criterion='entropy'表示使用信息增益,即ID3)
clf = DecisionTreeClassifier(criterion='entropy', random_state=42)
clf.fit(X, y)
# 7. 查看决策树结构
print(f"\n=== 决策树结构 ===")
tree_text = export_text(clf,
feature_names=['gender', 'Activity_info'],
class_names=le_churn.classes_)
print(tree_text)
# 8. 预测新样本
new_sample = np.array([[0, 0]]) # 男, 高活跃
prediction = clf.predict(new_sample)
print(f"\n新样本预测: {le_churn.inverse_transform(prediction)[0]}")
输出示例:
=== 原始数据 ===
gender Activity_info churn
0 男 高 否
1 女 高 否
2 男 低 是
3 女 高 否
4 男 中 是
5 女 低 是
6 男 高 否
7 女 中 是
8 男 低 是
9 女 高 否
=== 信息熵 ===
H(D) = 0.9710
=== 各特征的信息增益 ===
gender: 信息增益 = 0.0000
Activity_info: 信息增益 = 0.4245
=== 决策树结构 ===
|--- Activity_info <= 0.50
| |--- class: 否
|--- Activity_info > 0.50
| |--- Activity_info <= 1.50
| | |--- class: 是
| |--- Activity_info > 1.50
| | |--- class: 是
新样本预测: 否
6 重难点与易错提醒
- ❗重点:ID3核心思想是优先参考信息增益大的特征充当节点。
- ❗重点:信息增益 = 信息熵 - 条件熵。
- ❗重点:信息熵只看标签,与特征无关。
- ❗重点:条件熵按特征分组加权求和。
- ⚠️易错:信息熵计算时混淆特征和标签。
- ⚠️易错:条件熵的加权计算错误。
- 💡深入理解:信息增益越大,特征对分类越重要。
7 课堂问答精选
Q: ID3决策树的构建流程是什么?
A:
- 计算每个特征的信息增益
- 信息增益大的特征作为根节点
- 按特征值拆分子集
- 对剩余特征继续计算信息增益
- 信息增益大的作为下一层节点
- 以此类推,直到所有样本属于同一类或没有特征可用
Q: 如何选择根节点?
A: 分别计算所有特征的信息增益,信息增益最大的特征作为根节点。例如,性别和活跃度两个特征,分别计算它们的信息增益,比较大小,信息增益大的作为根节点。
8 本课小结
- ID3核心思想:优先参考信息增益大的特征充当节点。
- 构建流程:计算信息增益 → 选最大 → 拆分子集 → 继续。
- 案例:论坛客户流失,活跃度信息增益更大,作为根节点。
- API:DecisionTreeClassifier(criterion='entropy')。
9 延伸思考与实践
- 实践:用sklearn构建ID3决策树。
- 预习:上午内容回顾。
- 思考:ID3有什么缺点?