Cart树原理介绍
1 课程概览
本课讲解CART决策树(分类回归树)。CART既可以用于分类(基尼指数最小化),也可以用于回归(平方误差最小化)。重点讲解基尼值和基尼指数的计算方法,CART选择基尼指数最小的特征作为划分节点。
2 核心概念与定义
- CART:Classification and Regression Tree(分类回归树)。
- 基尼值:从数据集D中随机抽取两个样本,其类别标记不一致的概率。
- 基尼指数:各分类占比 × 基尼值的和,用于选择划分属性。
- 基尼指数最小化:CART分类的划分策略。
- 平方误差最小化:CART回归的划分策略。
3 算法与模型详解
3.1 CART决策树
全称:Classification and Regression Tree(分类回归树)
特点:
- 既可以用于分类,也可以用于回归
- 分类:基尼指数最小化
- 回归:平方误差最小化
读法:CART决策树(一般不念cut)
3.2 CART分类
划分策略:基尼指数最小化
基尼值定义:从数据集D中随机抽取两个样本,其类别标记不一致的概率
特点:
- 基尼值越小,数据纯度越高
- 基尼值越大,数据越混乱
3.3 CART回归
划分策略:平方误差最小化
理解:
- 类似最小二乘法
- 误差平方和最小
- 除以样本数 → 均方误差(MSE)
- 开根号 → 均方根误差(RMSE)
- 绝对值求和除以样本数 → 平均绝对误差(MAE)
3.4 基尼值计算
定义:从数据集D中随机抽取两个样本,其类别标记不一致的概率
公式: $$\text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2$$
其中:
- $p_k$:第k个类别的占比
- $K$:类别总数
理解:1 - 每个类别平方和
3.5 基尼指数计算
定义:选择划分后作为最优化属性的指标
公式: $$\text{GiniIndex}(D, A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} \text{Gini}(D_i)$$
其中:
- $\frac{|D_i|}{|D|}$:分类占比
- $\text{Gini}(D_i)$:该分类的基尼值
3.6 三种决策树对比
| 决策树 | 划分标准 | 策略 | 任务 |
|---|---|---|---|
| ID3 | 信息增益 | 越大越好 | 分类 |
| C4.5 | 信息增益率 | 越大越好 | 分类 |
| CART | 基尼指数 | 越小越好 | 分类+回归 |
3.7 基尼值示例
示例1:盒子里有10个红色小球
计算:
- 红色占比:$p = 10/10 = 1$
- $\text{Gini} = 1 - 1^2 = 1 - 1 = 0$
结论:基尼值=0,数据纯度最高(全是同一类)
示例2:盒子里有5个红球,5个蓝球
计算:
- 红色占比:$p_1 = 5/10 = 0.5$
- 蓝色占比:$p_2 = 5/10 = 0.5$
- $\text{Gini} = 1 - (0.5^2 + 0.5^2) = 1 - 0.5 = 0.5$
结论:基尼值=0.5,数据混乱
3.8 基尼值的特点
| 数据情况 | 基尼值 | 纯度 |
|---|---|---|
| 全是同一类 | 0 | 最高 |
| 两类各半 | 0.5 | 较低 |
| 类别越多 | 越大 | 越低 |
4 数学原理与推导
4.1 基尼值
$$\text{Gini}(D) = 1 - \sum_{k=1}^{K} p_k^2$$
4.2 基尼指数
$$\text{GiniIndex}(D, A) = \sum_{i=1}^{n} \frac{|D_i|}{|D|} \text{Gini}(D_i)$$
4.3 CART分类选择
$$A^* = \arg\min_A \text{GiniIndex}(D, A)$$
4.4 CART回归
$$A^* = \arg\min_A \sum_{i=1}^{n} \text{MSE}(D_i)$$
5 代码示例
import numpy as np
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):
"""计算基尼指数"""
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
# 1. 基尼值计算示例
print("=== 基尼值计算示例 ===")
# 示例1:全是同一类(10个红球)
labels1 = np.array(['红'] * 10)
print(f"10个红球: 基尼值 = {gini(labels1):.4f}") # 0.0
# 示例2:两类各半(5红5蓝)
labels2 = np.array(['红'] * 5 + ['蓝'] * 5)
print(f"5红5蓝: 基尼值 = {gini(labels2):.4f}") # 0.5
# 示例3:三类
labels3 = np.array(['红'] * 4 + ['蓝'] * 3 + ['绿'] * 3)
print(f"4红3蓝3绿: 基尼值 = {gini(labels3):.4f}")
# 示例4:完全混乱(10个不同类)
labels4 = np.array([str(i) for i in range(10)])
print(f"10个不同类: 基尼值 = {gini(labels4):.4f}")
# 2. 基尼指数计算示例
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'])
gi = gini_index(feature, labels)
print(f"基尼指数: {gi:.4f}")
# 详细计算过程
print("\n=== 详细计算过程 ===")
print(f"数据: labels={labels}")
print(f"特征: feature={feature}")
# 基尼值
gini_parent = gini(labels)
print(f"\n1. 父节点基尼值: {gini_parent:.4f}")
# 各子节点基尼值
for value in np.unique(feature):
subset = labels[feature == value]
gini_sub = gini(subset)
weight = len(subset) / len(labels)
contribution = weight * gini_sub
print(f" {value}: {len(subset)}/{len(labels)} = {weight:.4f}, 基尼值={gini_sub:.4f}, 贡献={contribution:.4f}")
print(f"\n2. 基尼指数: {gi:.4f}")
# 3. 比较不同特征的基尼指数
print("\n=== 比较不同特征的基尼指数 ===")
features = {
'特征1': np.array(['alpha', 'alpha', 'alpha', 'alpha', 'beta', 'beta']),
'特征2': np.array(['alpha', 'alpha', 'beta', 'beta', 'alpha', 'alpha']),
'特征3': np.array(['alpha', 'beta', 'alpha', 'beta', 'alpha', 'beta'])
}
for name, feat in features.items():
gi = gini_index(feat, labels)
print(f"{name}: 基尼指数 = {gi:.4f}")
print("\nCART选择基尼指数最小的特征作为划分节点")
# 4. 三种决策树对比
print("\n=== 三种决策树对比 ===")
print("ID3: 信息增益越大越好")
print("C4.5: 信息增益率越大越好")
print("CART: 基尼指数越小越好")
输出示例:
=== 基尼值计算示例 ===
10个红球: 基尼值 = 0.0000
5红5蓝: 基尼值 = 0.5000
4红3蓝3绿: 基尼值 = 0.6600
10个不同类: 基尼值 = 0.9000
=== 基尼指数计算示例 ===
基尼指数: 0.1667
=== 详细计算过程 ===
数据: labels=['A' 'A' 'A' 'B' 'B' 'B']
特征: feature=['alpha' 'alpha' 'alpha' 'alpha' 'beta' 'beta']
1. 父节点基尼值: 0.5000
alpha: 4/6 = 0.6667, 基尼值=0.3750, 贡献=0.2500
beta: 2/6 = 0.3333, 基尼值=0.0000, 贡献=0.0000
2. 基尼指数: 0.1667
=== 比较不同特征的基尼指数 ===
特征1: 基尼指数 = 0.1667
特征2: 基尼指数 = 0.4444
特征3: 基尼指数 = 0.5000
CART选择基尼指数最小的特征作为划分节点
=== 三种决策树对比 ===
ID3: 信息增益越大越好
CART: 基尼指数越小越好
6 重难点与易错提醒
- ❗重点:CART既能分类又能回归。
- ❗重点:分类用基尼指数最小化,回归用平方误差最小化。
- ❗重点:基尼值 = 1 - 各类别平方和。
- ❗重点:基尼指数越小越好(与ID3/C4.5相反)。
- ⚠️易错:混淆基尼值和基尼指数。
- ⚠️易错:CART是越小越好,ID3/C4.5是越大越好。
- 💡深入理解:基尼值表示数据混乱程度,越小纯度越高。
7 课堂问答精选
Q: CART决策树如何划分节点?
A: CART决策树使用基尼指数划分节点,选择基尼指数最小的特征作为划分节点(越小越好)。这与ID3(信息增益越大越好)和C4.5(信息增益率越大越好)相反。
Q: 基尼值和基尼指数有什么区别?
A:
- 基尼值:单个数据集的混乱程度,公式:1 - 各类别平方和
- 基尼指数:按特征划分后各子集基尼值的加权平均,用于选择划分特征 基尼值衡量单个数据集,基尼指数衡量划分后的整体混乱程度。
8 本课小结
- CART:分类回归树,既能分类又能回归。
- 分类:基尼指数最小化。
- 回归:平方误差最小化。
- 基尼值:1 - 各类别平方和。
- 基尼指数:越小越好。
- 对比:ID3/C4.5越大越好,CART越小越好。
9 延伸思考与实践
- 实践:用Python计算基尼值和基尼指数。
- 预习:三种决策树总结。
- 思考:为什么CART用基尼指数而不是信息增益?