决策树与随机森林
一、直观理解:一连串“如果…那么…”与群众投票
决策树把分类过程写成可阅读的规则链:先看贷款额度是否超过阈值,再看征信等级,再看收入……每一步把样本分到更纯的子集,叶子节点给出类别。
单棵树像一位经验丰富但容易偏执的专家——对训练数据记得太死就会过拟合。随机森林则请很多棵树各自在自助抽样样本和随机特征子集上生长,最后投票。一棵树可能看走眼,一群树的多数意见通常更稳。
- 决策树:可解释、易可视化,方差大;
- 随机森林:精度与稳定性显著提升,解释性转为特征重要性与单树示例。
二、适用场景与优缺点
| 类型 | 说明 |
|---|---|
| 适用场景 | 表格数据;存在非线性与特征交互;既要精度又要一定可解释性;特征量纲混杂、缺失与异常较多;需要特征重要性排序。 |
| 核心优点 | 树模型对单调变换不敏感;能刻画交互;随机森林不易过拟合到单树程度;可处理混合类型特征;训练可并行。 |
| 局限与缺点 | 单树不稳定;森林概率校准一般;外推能力弱;高基数类别特征需小心;深度学习式表示学习不是其强项;默认参数在极不平衡时需调整。 |
使用前检查:类别编码方式、是否按实体划分、评价指标是否对不平衡敏感、树深与最小叶样本是否约束过拟合。
三、核心原理
1. 树的生长:选择最佳分裂
对节点 中的样本,杂质常用基尼指数或熵。两类情形基尼为
候选分裂把节点分为 ,杂质下降(信息增益)为
选择使 最大的特征与阈值。回归树则最小化子节点平方误差。
停止条件:达到最大深度、节点样本过少、增益过小,或事后剪枝。
2. 随机森林
对 :
- 对训练集做 bootstrap 抽样 ;
- 在 上长树;每个分裂仅在随机抽取的 个特征中选最优(分类常用 );
- 预测时分类投票、回归平均。
袋外(OOB)样本可近似估计泛化误差,并用于排列重要性。
3. 特征重要性
- 不纯度减少累计:特征在所有分裂中带来的 之和;
- 排列重要性:打乱某列后 OOB 误差上升越多,该特征越重要。
四、关键决策
| 决策点 | 建议 |
|---|---|
MaxNumSplits / 深度 | 单树宜限制深度;森林可稍深,靠平均降方差 |
MinLeafSize | 增大可抑制过拟合,小样本尤重要 |
| 树棵数 | 先 100–500,看 OOB 误差是否还在下降 |
NumPredictorsToSample | 分类默认 ,可网格搜索 |
| 类别权重 | 不平衡时用 Prior 或 Cost |
| 单树 vs 森林 | 要规则解释 → 浅树;要精度 → 森林 |
| 与 GBDT | 森林方差小、调参宽;GBDT 常更高精但更敏感 |
五、MATLAB 示例
% 特征:年龄、收入、负债率;标签 1=违约
X = [
25 4.5 0.45;
40 9.0 0.20;
33 6.2 0.38;
50 12.0 0.15;
29 5.0 0.50;
45 10.5 0.22;
36 7.0 0.40;
52 11.0 0.18
];
y = [1; 0; 1; 0; 1; 0; 1; 0];
varNames = ["年龄","收入","负债率"];
% ---- 单棵分类树 ----
tree = fitctree(X, y, ...
"PredictorNames", cellstr(varNames), ...
"MaxNumSplits", 8, ...
"MinLeafSize", 1, ...
"SplitCriterion", "gdi");
view(tree, "Mode", "graph"); % 可视化
yhatTree = predict(tree, X);
disp("单树混淆矩阵:"); disp(confusionmat(y, yhatTree));
% 交叉验证剪枝相关损失
cvTree = crossval(tree, "KFold", 4);
fprintf("单树 CV loss = %.3f\n", kfoldLoss(cvTree));
% ---- 随机森林(Bagged 树)----
rf = TreeBagger(100, X, y, ...
"Method", "classification", ...
"OOBPrediction", "on", ...
"OOBPredictorImportance", "on", ...
"MinLeafSize", 1, ...
"NumPredictorsToSample", "sqrt");
% OOB 误差曲线
figure;
plot(oobError(rf));
xlabel("树的棵数"); ylabel("OOB 误差");
title("随机森林 OOB 误差");
% 特征重要性
imp = rf.OOBPermutedPredictorDeltaError;
figure;
bar(imp);
set(gca, "XTickLabel", varNames);
ylabel("OOB 排列重要性");
title("特征重要性");
% 预测
[label, score] = predict(rf, X);
label = str2double(label); % TreeBagger 返回 cellstr
disp("森林混淆矩阵:"); disp(confusionmat(y, label));
也可用 fitcensemble(X,y,"Method","Bag","NumLearningCycles",100) 得到类似 bagging 森林。
六、如何解释结果
- 单树:从根到叶读出规则,检查阈值是否符合业务常识;
- 森林投票比例:可当作粗糙概率,必要时做概率校准;
- 重要性排序:指出驱动分类的关键变量,但注意相关特征会分摊重要性;
- OOB 曲线:确认树的数量是否足够;
- 错误案例:看被多数树投错的样本是否处于边界或标签噪声;
- 报告:树深/叶大小、棵数、OOB 或 CV 指标、Top 特征、与 Logistic 基线对比。
七、常见误区
1. 把训练准确率 100% 的深树当作成绩
未约束的树极易过拟合,必须以 CV/OOB/测试集为准。
2. 解释森林时假装它是单条规则
森林是分布在多棵树上的平均行为;需要规则时抽浅树或用规则提取/SHAP。
3. 重要性当作因果
重要性高只说明对预测有用,不证明因果。
4. 忽略类别不平衡
准确率虚高时,看混淆矩阵与少数类召回。
5. 对时间序列随机打乱划分
有时间结构时应用前向验证,避免未来信息泄漏。
八、小结
决策树用递归二分把特征空间切成可解释区域;随机森林通过自助抽样与随机特征,降低单树方差,形成稳健的非线性分类器。
赛题中二者是表格数据的主力:先用浅树讲清逻辑,再用森林冲刺精度,并用重要性与若干代表路径支撑论文叙事。