随机森林与 Bagging
一句话定义
Bagging 对训练集做自助重采样训练多个模型并取平均(分类投票),随机森林在此基础上让每棵树的每次分裂只看随机特征子集,用「去相关的多棵深树」把方差压到单树的零头。
为什么重要
随机森林是「开箱即用」的强基线:调参少、对特征尺度与异常值鲁棒、并行训练快、自带 OOB 评估与特征重要性。在表格数据任务中它常是第一个值得认真跑的模型,也是理解「为什么集成有效」的最佳教具。
前置知识
决策树:信息增益、增益率与基尼指数 的决策树;偏差-方差分解与过拟合 的方差概念。
核心概念
- 自助采样(bootstrap):有放回抽 n 个样本,约 36.8% 样本不进该棵树的训练集(OOB 部分)。
- Bagging:bootstrap 聚合,多个「脾气不同」的模型投票/平均。
- 特征随机子集:每次分裂只从 √p(分类)或 p/3(回归)个特征中选——关键的去相关机制。
- OOB 误差(Out-of-Bag):每棵树用没见过它的样本评估,再汇总,相当于免费的交叉验证。
- 并行集成:各树独立可并行(与 Boosting 的串行相对)。
直观类比
会诊:一个医生(单树)看诊有个人偏见(高方差),请 500 个各自见过不同病人(bootstrap)、且每人只被允许看部分检查单(特征子集)的医生投票——个别人的怪判断被稀释。如果所有医生看同样的材料(完全相关的树), averaging 几乎无效:去相关是平均起效的前提。
原理与机制
对 B 个方差 σ2、两两相关系数 ρ 的模型的平均,方差为:
B → ∞ 时第一项存留——平均消不掉相关性带来的方差下限。Bagging 只做重采样,ρ 仍很高(树总是先切最强的那个特征);随机森林用特征子集强制去相关,压低 ρ,从而突破 Bagging 的下限。代价:单棵树有效信息变少、偏差略升,通常净收益显著为正。集成几乎不改变偏差(平均的期望仍是期望),这是它「治方差不治偏差」的理论根据。
公式与推导
回归下的平均:f̂avg(x) = 1B∑b=1B f̂b(x),
同方差相关结构下化简为 ρσ2 + (1-ρ)σ2/B。分类按多数票/平均概率,直觉相同。OOB 估计的理论依据:每棵树的 OOB 样本与训练样本同分布且独立于该树,汇总后近似交叉验证的无偏估计。
图示
训练集 D
┌────┬────┬────┬────┐
▼ ▼ ▼ ▼ ▼ bootstrap 采样
D*₁ D*₂ D*₃ D*₄ D*B
│ │ │ │ │ 每棵树分裂时只看 √p 个特征
树₁ 树₂ 树₃ 树₄ 树B (独立并行训练)
└────┴────┴───┬┴────┘
▼
平均 / 多数投票 → 预测
(OOB 样本旁路评估每棵树 → OOB 误差)实例或案例
对单树与森林在同一数据上量化方差差异:
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
import numpy as np
X, y = load_breast_cancer(return_X_y=True)
accs = {"单树": [], "森林": []}
for seed in range(30): # 30 次不同划分,看成绩波动
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.3, random_state=seed)
t = DecisionTreeClassifier(random_state=seed).fit(X_tr, y_tr)
f = RandomForestClassifier(n_estimators=300, random_state=seed, n_jobs=-1).fit(X_tr, y_tr)
accs["单树"].append(t.score(X_te, y_te)); accs["森林"].append(f.score(X_te, y_te))
for k, v in accs.items():
print(f"{k}: 均值={np.mean(v):.3f} 标准差={np.std(v):.3f}")典型结果:均值相近或森林略高,但森林的跨划分标准差小得多——方差被压掉的直接证据。
常见误区
- 认为「树越多越好,但必须大量调参」:B 加到误差平台即可,默认参数常已可用;真正值得调的是
max_features(去相关强度)与树深。 - 把不纯度重要性当真(高基数/连续特征虚高):诊断用置换重要性(见 kp-014)。
- 用随机森林做时间序列外推:树只能输出训练集见过的数值范围,无法外推趋势(分段常数本质)。
与其他知识点的关系
偏差-方差分解与过拟合 的方差公式是本节的数学骨架;Boosting 与 AdaBoost/梯度提升树 GBDT 与 XGBoost 是另一条集成路线(串行降偏差);树模型可解释性:特征重要性与 SHAP 的置换重要性提供更可信的森林解读;超参数调优:网格、随机与贝叶斯搜索 中随机森林的超参数搜索空间通常很小——这是它工程友好的原因。
自测题
- Bagging 与随机森林最关键的区别是什么,为什么这个区别重要?
- 要点:分裂时随机特征子集强制树间去相关;由 ρσ2 + (1-ρ)σ2/B,相关性下限不降则平均收益封顶。
- OOB 误差为什么能替代验证集?
- 要点:每棵树的 OOB 样本未参与该树训练,同分布独立,汇总后近似 k 折 CV,免费且无重复建模成本。
- 随机森林主要降低偏差还是方差?
- 要点:方差(平均不改变期望);单树已是低偏差模型,森林在其上收窄波动。
延伸阅读
Breiman, Random Forests(Machine Learning, 2001);周志华《机器学习》第 8 章。