HelloAI
L2 第 5 篇 🐣 难度 🕒 13 分钟

随机森林 + Boosting:让一群弱学习器变成超人

单棵树平庸,一群树投票就能逆天。Kaggle 十年霸主 XGBoost 的来历,就在这一篇。

阿莱
2026/6/28

L2-04 结尾我说”单棵树弱、集成起来无敌”——这一篇展开讲。

集成学习(Ensemble Learning)的核心思想:

多个”差不多”的弱模型组合起来,能远超单个强模型。

这不是 ML 独创——人类社会也是。陪审团(多人独立判断)比单个法官准。专家组(专家共识)比单个专家强。算法世界把这个原则发挥到了极致

两大思路

集成学习有两大流派,完全不同的”组合方式”

流派中文核心思想代表
Bagging装袋训 N 个独立模型,投票随机森林
Boosting提升训 N 个串行模型,后者纠正前者的错XGBoost、LightGBM

两者都用决策树作为”基模型”——但组合方式根本不同。

一、Bagging 和随机森林

Bagging 原理

Bagging = Bootstrap Aggregating

  1. 从训练数据有放回采样,构造 N 份”略有差异”的子数据集
  2. 在每份上独立训练一棵树
  3. 预测时让 N 棵树投票(分类)或求平均(回归)

关键:每棵树都是在”略有不同”的数据上训出来的,所以它们的错误不会相关——投票时错误互相抵消。

随机森林(Random Forest)

随机森林 = Bagging + 额外的随机性

每棵树训练时,每次节点分裂只考虑随机选的部分特征(不是全部)。

这一招让每棵树更”独立”,投票效果更好。

用 sklearn

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 100 棵树的随机森林(默认值就很好)
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)

print(f"准确率: {rf.score(X_test, y_test):.3f}")  # 通常 96-97%

L2-04 的单棵决策树拿到 93%——改一行代码,提升到 97%。这就是集成的威力。

重要超参数

参数推荐起点
n_estimators100-500(树越多越稳,但慢)
max_depthNone(让树长满)或 10
max_features’sqrt’(每次分裂用 sqrt(N) 个特征)
min_samples_leaf1-5

随机森林的优势

✅ 几乎不需要调参就能跑出好结果 ✅ 不容易过拟合(树多 = 投票更稳) ✅ 提供特征重要度(决策树的优势保留) ✅ 能并行训练(每棵树独立)

❌ 慢(100 棵树 vs 1 棵树) ❌ 模型大(要存 100 棵树)

二、Boosting 和 XGBoost

Boosting 原理

完全相反的思路。串行训练:

  1. 训第 1 棵树
  2. 看它错在哪——把”错的样本”权重提高
  3. 训第 2 棵树(用调整后的权重)—— 它专注修正第 1 棵的错
  4. …重复 N 次
  5. 最终预测 = N 棵树的加权和

关键直觉:每棵新树都在”补”前面所有树留下的错

Gradient Boosting

更优雅的版本——把”修正错误”用梯度形式表达:

  1. 当前预测和真实值的差 = 残差
  2. 训一棵新树拟合残差
  3. 加到当前预测上

听起来奇怪?想想 L1-03 的梯度下降——Gradient Boosting 在函数空间做梯度下降。每加一棵树就是沿着损失函数的”负梯度方向”走一步。

XGBoost / LightGBM / CatBoost

XGBoost 是 Gradient Boosting 的”工程化奇迹”——2014 年陈天奇开源后席卷 Kaggle。

后来 Microsoft 出了 LightGBM(更快),Yandex 出了 CatBoost(处理类别特征好)。

今天工业界三巨头:XGBoost、LightGBM、CatBoost——它们的算法都基于 Gradient Boosting,工程优化和细节不同。

用 XGBoost

# 需要先 pip install xgboost
import xgboost as xgb
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = xgb.XGBClassifier(
    n_estimators=200,
    learning_rate=0.05,
    max_depth=4,
    random_state=42
)
model.fit(X_train, y_train,
          eval_set=[(X_test, y_test)],
          verbose=False)

print(f"准确率: {model.score(X_test, y_test):.3f}")  # 通常 97-98%

一行配置,就能拿到深度学习级别的效果

重要超参数

参数作用调参方向
n_estimators树的数量100-1000
learning_rate每棵树的贡献权重0.01-0.1(小则需更多树)
max_depth单棵树深度3-8(不像随机森林那么深)
subsample每棵树用多少比例样本0.6-1.0
colsample_bytree每棵树用多少比例特征0.5-1.0
reg_lambdaL2 正则化0-1

XGBoost 调参是个艺术,但用默认值通常已经很好——别一上来就调参。

Bagging vs Boosting:怎么选

维度Random ForestXGBoost
训练速度慢(独立但棵数多)慢(串行无法并行)
调参敏感度
过拟合风险中(需要 early stopping)
性能上限中等-高最高
推荐场景新项目 baseline调好了能赢 Kaggle

我的经验法则

  • 时间紧 → Random Forest(一行搞定不亏)
  • 追求最优 → XGBoost(值得花时间调)
  • 数据巨大 → LightGBM(最快)

为什么集成这么强

数学直觉

如果 N 个模型的错误互相不相关(独立),那么投票后的错误率 ≈ 单模型错误率的 N 次方。

假设单模型对率 70%。 11 个独立模型投票,多数对的概率 ≈ 91%! 21 个 → 97%!

这就是为什么 Kaggle 上集成模型几乎永远赢

但有个前提:模型必须独立比随机好。如果都犯同样错,投票也救不了。

现实:模型之间往往不完全独立——它们用同一份数据、同类算法。所以实际收益没有理论那么夸张。但仍然显著比单模型好

Stacking:终极组合

更狠的玩法:用一个模型来学”怎么组合其它模型”

  1. 训练 N 个不同的基模型(决策树、神经网络、线性回归、SVM…)
  2. 用一个”元模型”(meta-learner)学习”怎么权衡这 N 个的输出”
from sklearn.ensemble import StackingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC

stack = StackingClassifier(
    estimators=[
        ('rf', RandomForestClassifier()),
        ('xgb', xgb.XGBClassifier()),
        ('svc', SVC(probability=True))
    ],
    final_estimator=LogisticRegression()
)
stack.fit(X_train, y_train)

Kaggle 顶级选手用这一招的多——但工业部署难(模型多、推理慢)。

工业真实情况

Kaggle 比赛 70%+ 的 winning solution 都基于 GBDT 类算法(XGBoost / LightGBM / CatBoost)——尤其是表格数据。

神经网络在结构化表格数据上通常打不过 GBDT——除非数据极大(百万+)且特征复杂。

这是为什么 ML 工程师面试必考 XGBoost——它是真正的”产线武器”。

💡 一个工业故事

2023 年某大厂的推荐系统经历过:

  • 第一代:手工特征 + 逻辑回归
  • 第二代:手工特征 + GBDT → 显著提升
  • 第三代:手工特征 + 深度学习 → 仅小幅提升,运维成本爆炸
  • 最终选择:手工特征 + GBDT 作为主线 + 深度学习做局部增强

结论:在很多业务上,GBDT 仍然是更经济的选择。深度学习不是万灵药。

下一篇:《K-Means 聚类:最经典的无监督算法》 —— 离开监督学习,进入无标签的世界。

📬

读到这里说明你认真在学 🎯

订阅每周精选 —— 下一篇新文章 / 新可视化第一时间送到邮箱。

💬

讨论区

· 用 GitHub 账号登录评论
⚠️ Giscus 评论未配置 —— 在 src/components/Comments.astro 顶部填入 仓库 ID 和分类 ID(见组件注释里的配置步骤)。