共计 2191 个字符,预计需要花费 6 分钟才能阅读完成。
背景介绍
决策树是机器学习中最直观的算法之一,广泛应用于金融风控、医疗诊断和推荐系统。CART(Classification and Regression Trees)算法因其以下优势成为工业界首选:

- 同时支持分类和回归任务
- 使用二元分裂(每次只分两个分支)简化模型结构
- 内置剪枝机制有效防止过拟合
技术对比:CART vs ID3/C4.5
- 分裂标准 :
- ID3 使用信息增益(易偏向多值特征)
- C4.5 使用增益率(解决 ID3 缺陷)
-
CART 使用基尼系数(计算效率更高)
-
输出类型 :
- ID3/C4.5 仅支持分类
-
CART 支持分类和回归
-
树结构 :
- ID3/C4.5 生成多叉树
- CART 生成二叉树
核心实现
1. 特征选择:基尼系数
基尼系数反映数据不纯度,计算复杂度低于信息熵:
def gini_index(groups, classes):
n_instances = sum(len(group) for group in groups)
gini = 0.0
for group in groups:
size = len(group)
if size == 0:
continue
score = 1.0
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score -= p ** 2
gini += score * (size / n_instances)
return gini
2. 递归建树流程
- 计算当前节点基尼指数
- 遍历所有特征及其可能分割点
- 选择使基尼系数下降最大的特征进行分裂
- 递归处理子节点直到终止条件(如深度限制)
3. 剪枝策略
-
预剪枝 :在建树过程中通过参数控制
from sklearn.tree import DecisionTreeClassifier # 关键参数控制 model = DecisionTreeClassifier( max_depth=5, # 树的最大深度 min_samples_split=10, # 节点继续分裂的最小样本数 min_impurity_decrease=0.01 # 分裂需要的最小不纯度下降 ) -
后剪枝 :先构建完整树,再自底向上剪枝
Python 实现对比
scikit-learn 版本(推荐生产使用)
from sklearn.datasets import load_iris
from sklearn import tree
import matplotlib.pyplot as plt
# 加载数据
iris = load_iris()
X, y = iris.data, iris.target
# 训练模型
clf = tree.DecisionTreeClassifier(criterion='gini', max_depth=3)
clf = clf.fit(X, y)
# 可视化
plt.figure(figsize=(12,8))
tree.plot_tree(clf, feature_names=iris.feature_names,
class_names=iris.target_names, filled=True)
plt.show()
原生实现(理解原理)
class Node:
def __init__(self, feature=None, threshold=None, left=None, right=None, value=None):
self.feature = feature # 分裂特征
self.threshold = threshold # 分裂阈值
self.left = left # 左子树
self.right = right # 右子树
self.value = value # 叶节点预测值
# 完整实现代码较长,此处展示核心分裂函数
def split_dataset(X, y, feature_index, threshold):
left_mask = X[:, feature_index] <= threshold
right_mask = ~left_mask
left = (X[left_mask], y[left_mask])
right = (X[right_mask], y[right_mask])
return left, right
性能优化实战
连续特征处理
- 对特征值排序
- 取相邻值中点作为候选分割点
- 选择最优分割点
并行计算
from sklearn.ensemble import BaggingClassifier
# 通过装袋法并行训练多棵树
model = BaggingClassifier(DecisionTreeClassifier(),
n_estimators=10,
max_samples=0.8,
n_jobs=-1 # 使用所有 CPU 核心
)
常见问题解决方案
过拟合识别
- 训练集准确率 >> 测试集准确率
- 决策树深度过大(超过 15 层)
类别不平衡
- 调整 class_weight 参数
model = DecisionTreeClassifier(class_weight='balanced') - 对少数类样本进行过采样
业务落地建议
- 金融风控 :
- 用 SHAP 值解释单笔贷款拒批原因
-
设置动态评分阈值
-
医疗诊断 :
- 结合临床指标构建决策路径
- 输出可解释的诊断规则
思考题
在特征维度极高(如 >1000 维)的情况下,可以考虑:
- 先进行特征选择(如基于方差或互信息)
- 使用随机森林的特征重要性进行筛选
- 采用近似算法(如 Histogram-based Gradient Boosting)
决策树的魅力在于其可解释性与高效性。当业务需要模型 ” 讲道理 ” 时,CART 算法永远是可靠的选择。
正文完
