共计 1408 个字符,预计需要花费 4 分钟才能阅读完成。
决策树是机器学习中最直观易懂的算法之一,常用于分类和回归任务,比如客户分群、医疗诊断等场景。今天我们用一个简化版的鸢尾花数据集,手把手带你实现 CART 决策树的全流程。

一、数据准备:构造示例数据集
这里我们使用 sklearn 自带的鸢尾花数据集,但只保留前两个特征和两个类别,方便可视化:
from sklearn.datasets import load_iris
import pandas as pd
# 加载并简化数据集
iris = load_iris()
df = pd.DataFrame(iris.data[:, :2], columns=['sepal_length', 'sepal_width'])
df['target'] = iris.target
df = df[df['target'].isin([0,1])] # 只保留 setosa 和 versicolor 两类
二、分裂准则:基尼系数实战计算
CART 决策树默认使用基尼系数作为分裂标准,其计算公式为:
$$Gini = 1 – \sum_{i=1}^{k}p_i^2$$
我们来手动计算第一个特征的划分效果:
- 按 sepal_length<=5.4 划分时:
- 左节点:50 个样本中 48 个是类别 0
- 右节点:50 个样本中 2 个是类别 0
- 基尼系数 = (50/100)(1-(48/50)^2-(2/50)^2) + (50/100)(1-(2/50)^2-(48/50)^2) ≈ 0.168
三、递归构建决策树
决策树的生长本质是递归分区过程,伪代码如下:
def build_tree(node):
if 当前节点样本纯度高 or 达到终止条件:
return 叶子节点
找到最佳分裂特征和阈值
创建左右子节点
build_tree(左节点)
build_tree(右节点)
四、Python 完整实现
from sklearn.tree import DecisionTreeClassifier, export_graphviz
import graphviz
# 训练模型
tree = DecisionTreeClassifier(criterion='gini', max_depth=3)
tree.fit(df[['sepal_length', 'sepal_width']], df['target'])
# 可视化
dot_data = export_graphviz(tree, feature_names=['sepal_length', 'sepal_width'],
class_names=['setosa', 'versicolor'], filled=True)
graphviz.Source(dot_data)
执行后会生成清晰的决策树图,其中:
– 颜色深浅表示类别纯度
– samples 显示当前节点样本数
– value 显示类别分布
– gini 是该节点的基尼系数
五、避坑指南
- 连续特征处理 :
- CART 本身支持连续特征
-
关键点是找到最佳分割阈值
-
类别不平衡 :
- 设置 class_weight=’balanced’
-
或对少数类过采样
-
防止过拟合 :
- 限制 max_depth(通常 3 - 5 层)
- 设置 min_samples_leaf(建议 5 -10)
- 使用 ccp_alpha 参数进行代价复杂度剪枝
六、思考进阶
- 随机森林如何通过多个决策树提升效果?
- 相比逻辑回归,决策树更适合哪些场景?
- 当特征维度很高时,如何优化决策树的计算效率?
通过这个小案例,相信你已经掌握了决策树的核心要点。建议尝试修改参数观察树结构变化,这是理解算法最好的方式!
正文完
