共计 1490 个字符,预计需要花费 4 分钟才能阅读完成。
为什么需要 CART 决策树
CART(Classification and Regression Tree)是机器学习中最直观的算法之一,特别适合处理带有清晰逻辑规则的数据。比如银行判断贷款风险时,会依次考察申请人的年龄、收入、信用记录等特征,这种层层递进的判断逻辑,正是决策树的核心理念。

从鸢尾花数据集看分类过程
我们以经典的鸢尾花数据集为例,演示如何用 Gini 系数构建分类树。数据集包含 150 个样本,每个样本有 4 个特征(花萼长度 / 宽度、花瓣长度 / 宽度)和 3 个类别(Setosa/Versicolor/Virginica)。
关键步骤拆解
- 计算初始 Gini 不纯度
- 假设当前节点有 50 个 Setosa、50 个 Versicolor、50 个 Virginica
-
Gini = $1 – (\frac{50}{150})^2 – (\frac{50}{150})^2 – (\frac{50}{150})^2 = 0.6667$
-
寻找最佳分裂特征
- 遍历所有特征的可能分割点
-
对花瓣长度≤2.45cm 时:
- 左节点 50 个 Setosa,右节点 50+50 其他种类
- Gini 左 =0,Gini 右 =0.5
- 加权 Gini=0.3333,信息增益最大
-
递归构建子树
- 对右节点继续寻找最佳分裂,直到满足停止条件
Python 代码实现
from sklearn.tree import DecisionTreeClassifier
import pandas as pd
from sklearn.datasets import load_iris
# 加载数据
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
# 建模关键参数说明
# max_depth: 控制树的最大深度避免过拟合
# min_samples_split: 节点最少样本数
model = DecisionTreeClassifier(criterion='gini',
max_depth=3,
min_samples_split=5)
model.fit(df, iris.target)
# 特征重要性分析
print(dict(zip(iris.feature_names, model.feature_importances_)))
# 输出示例:{'花瓣长度': 0.92, '花瓣宽度': 0.08, ...}
工程实践中的关键技巧
处理连续型特征
- 排序后取相邻值的中位数作为候选分割点
- 使用
sklearn.preprocessing.KBinsDiscretizer分箱处理
缺失值处理
- 单独建立缺失值分支
- 将缺失样本分配到增益最大的子节点
剪枝优化
- 预剪枝参数示例:
max_leaf_nodes: 限制叶节点总数min_impurity_decrease: 分裂需要的最小增益- 后剪枝通过
ccp_alpha参数控制复杂度
可视化方法
from sklearn.tree import export_graphviz
import graphviz
dot_data = export_graphviz(model,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True)
graphviz.Source(dot_data)
思考与延伸
- 算法对比:
- ID3 仅支持离散特征,C4.5 引入信息增益比处理连续值
-
CART 的二叉树结构计算效率更高
-
实际应用限制:
- 金融场景中单棵树的稳定性较差
- 需要配合随机森林等集成方法提升效果
最终建议在 Jupyter Notebook 中逐行运行示例代码,通过调整参数观察树结构变化,这是掌握决策树最有效的方式。
正文完
