共计 1905 个字符,预计需要花费 5 分钟才能阅读完成。
CART 决策树作为经典的机器学习算法,既能处理分类任务也能解决回归问题,其核心价值在于通过树状结构直观呈现决策逻辑,同时具备优秀的可解释性。

一、新手常见痛点分析
-
信息增益计算的误区:
许多初学者误以为信息增益越大越好,实际上过度追求信息增益会导致选择取值较多的特征(如 ID 类特征),反而降低模型泛化能力。正确的做法是使用基尼系数或信息增益率进行特征选择。 -
停止条件的设定陷阱:
过早停止(如 max_depth 设置过小)会导致欠拟合,而放任树生长(如不设 min_samples_leaf)必然引发过拟合。建议通过交叉验证寻找最佳参数组合。
二、核心实现流程图解
flowchart TD
A[开始] --> B{是否达到停止条件?}
B -->| 是 | C[生成叶子节点]
B -->| 否 | D[计算所有特征基尼系数]
D --> E[选择最优分裂特征和阈值]
E --> F[创建分裂节点]
F --> G[递归处理左子树]
F --> H[递归处理右子树]
G & H --> B
C --> I[返回预测值]
三、关键代码实现
import numpy as np
# 计算基尼系数(Gini Index)def gini_index(groups, classes):
"""
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
# 计算每个类别的比例
class_counts = [row[-1] for row in group].count
score = sum((count/size)**2 for count in class_counts)
# 加权计算子集基尼系数
gini += (1.0 - score) * (size/n_instances)
return gini
# 连续值分箱处理示例
def find_best_split(data, feature_idx):
unique_values = sorted(set(row[feature_idx] for row in data))
thresholds = [(unique_values[i]+unique_values[i+1])/2
for i in range(len(unique_values)-1)]
best_gini = float('inf')
for threshold in thresholds:
left = [row for row in data if row[feature_idx] <= threshold]
right = [row for row in data if row[feature_idx] > threshold]
current_gini = gini_index([left, right], np.unique(data[:,-1]))
# 边界条件:避免空分裂
if len(left)==0 or len(right)==0:
continue
if current_gini < best_gini:
best_gini = current_gini
best_threshold = threshold
return best_threshold, best_gini
四、实战避坑指南
- 连续值分箱处理:
- 必须对边界值进行单独检查(如示例代码中的空集判断)
- 建议先对连续特征排序后再计算候选切分点
-
实际工程中可考虑等频分箱预处理
-
可视化防重叠技巧:
- 使用
sklearn.tree.plot_tree时调整max_depth参数 - 设置
fontsize参数放大节点字体 - 通过
plt.figure(figsize=(20,10))扩大画布 - 导出为 PDF 矢量图后可用 AI 软件二次排版
五、延伸思考
- 算法对比:
- ID3/C4.5 只能处理分类任务,CART 可同时处理回归问题
- CART 使用基尼系数计算更高效,但 ID3 系列对缺失值更鲁棒
-
sklearn 实际实现的是优化版的 CART 算法
-
可视化优化:
from sklearn.tree import plot_tree plt.figure(figsize=(15,8)) plot_tree(model, filled=True, feature_names=feature_names, class_names=target_names, rounded=True, fontsize=10) plt.savefig('tree.pdf', bbox_inches='tight')
在实践中,建议先用 max_depth=3 生成小树观察结构,再逐步调大深度。记住:决策树的优势不在于绝对精度,而在于业务可解释性——这是很多新手容易忽视的关键点。
正文完
