共计 1934 个字符,预计需要花费 5 分钟才能阅读完成。
决策树在特征工程中的核心价值
决策树通过递归分割数据空间,能自动识别最具区分度的特征组合。其产生的 if-else 规则天然可解释,特别适合需要特征重要性分析的场景。相比神经网络等黑盒模型,决策树在特征交互关系的可视化呈现上具有独特优势。

算法数学原理对比
信息熵(ID3)
- 熵衡量样本集合的混乱程度,计算公式:
H(D) = -Σ(p_k * log2(p_k)) - 信息增益 = 父节点熵 – 加权子节点熵
信息增益率(C4.5)
- 解决 ID3 对多值特征的偏好问题:
Gain_ratio(D,A) = Gain(D,A) / IV(A) IV(A) = -Σ(|D_v|/|D| * log2(|D_v|/|D|))
基尼系数(CART)
- 衡量数据不纯度的替代指标:
Gini(D) = 1 - Σ(p_k^2) - 计算效率比熵更高(省去对数运算)
CART 二叉树构建全流程
节点类定义
class TreeNode:
def __init__(self, feat_idx=None, threshold=None,
left=None, right=None, value=None):
self.feat_idx = feat_idx # 分裂特征索引
self.threshold = threshold # 分裂阈值
self.left = left # 左子树
self.right = right # 右子树
self.value = value # 叶节点预测值
基尼系数计算实现
def gini_impurity(y):
m = y.shape[0]
return 1.0 - sum((np.sum(y == c) / m) ** 2 for c in np.unique(y))
递归分裂逻辑
-
寻找最佳分裂特征和阈值:
def find_best_split(X, y): best_gini = float('inf') best_idx, best_thresh = None, None for feat_idx in range(X.shape[1]): thresholds = np.unique(X[:, feat_idx]) for thresh in thresholds: left_idx = X[:, feat_idx] <= thresh gini = (len(y[left_idx]) * gini_impurity(y[left_idx]) + len(y[~left_idx]) * gini_impurity(y[~left_idx])) / len(y) if gini < best_gini: best_gini = gini best_idx = feat_idx best_thresh = thresh return best_idx, best_thresh -
递归构建树:
def build_tree(X, y, max_depth=5, min_samples_split=2): if len(y) < min_samples_split or max_depth <= 0: return TreeNode(value=np.argmax(np.bincount(y))) feat_idx, thresh = find_best_split(X, y) left_idx = X[:, feat_idx] <= thresh left = build_tree(X[left_idx], y[left_idx], max_depth-1, min_samples_split) right = build_tree(X[~left_idx], y[~left_idx], max_depth-1, min_samples_split) return TreeNode(feat_idx, thresh, left, right)
剪枝策略实战分析
预剪枝方法
- 最大深度限制
- 节点最小样本数
- 分裂增益阈值
后剪枝步骤
- 先构建完整树
- 自底向上计算剪枝前后的验证集准确率
- 保留提升准确率的剪枝操作
生产环境避坑指南
类别特征处理
- 有序类别:转换为数值编码
- 无序类别:执行 one-hot 编码
缺失值应对方案
- 分裂时:将缺失样本分配到增益更大的分支
- 预测时:同时遍历左右子树并加权平均结果
延伸思考方向
- 如何改造当前实现以支持连续特征动态分箱?
- 能否通过特征采样实现随机森林的并行化训练?
- 当类别极度不均衡时,基尼系数是否需要加权调整?
基尼系数 vs 交叉熵
- 基尼系数:计算更高效,对类别分布变化更敏感
- 交叉熵:对错误分类惩罚更重,理论上有更好泛化性
手动计算示例
假设某节点有 10 个样本:[A 类 6 个, B 类 4 个]
– 基尼系数 = 1 – (0.6² + 0.4²) = 0.48
– 熵 = -(0.6log2(0.6) + 0.4log2(0.4)) ≈ 0.971
树深度与模型偏差方差
- 浅树:高偏差(欠拟合)
- 适当深度:偏差方差平衡
- 深树:高方差(过拟合)
通过控制 max_depth 参数,可以实现模型复杂度的精确调控。建议从 3 - 5 层开始,逐步增加深度观察验证集表现变化。
正文完
