哈喽,大家好~

咱们今天来聊聊随机森林 vs AdaBoost vs GBDT:三大集成学习算法的系统对比。

首先,简单来说,随机森林采用并行的Bagging思想,用大量随机化的决策树来降低方差),鲁棒、几乎不容易过拟合,训练可并行化。

AdaBoost过“关注错分样本”的加权策略,把弱学习器串行地组合成强学习器,等价于逐次最小化指数损失的逐步加法模型。对噪声和离群点敏感。

GBDT(Gradient Boosted Decision Trees)把提升(boosting)推广为梯度下降的加法模型,每一步拟合当前负梯度(残差),可以用任意可微损失,灵活且效果强,但训练顺序性强(不易并行化)。

下面,咱们分开聊聊具体的算法模型~

随机森林

bootstrap 重采样构建多棵决策树(每棵树训练不同的样本子集),并且在构造树的每个节点只随机考虑部分特征来寻找最佳分裂(feature bagging)。最后用多数投票(分类)或平均(回归)来融合多棵树的预测,从而显著降低方差而不明显增加偏差。

主要组成

  • 训练集:
  •   棵树在 bootstrap 样本上训练,表示为 ,总共有  棵树。
  • 预测(回归)
  • 预测(分类,多数投票)

假设每棵树的预测是均值为 ,方差为 ,树间的相关系数为 (pairwise correlation),则平均后的方差为:

解释:当  很小(树相互独立),方差近似为 ;若  接近 1,方差几乎不下降。随机森林通过样本随机化 + 特征随机化来减小 

决策树中常用的分裂准则

分类:Gini impurity  信息熵

Gini:

熵:

回归:最小化均方误差(MSE)(在节点用样本均值做预测)

AdaBoost

AdaBoost 是将弱学习器(通常是深度非常小的决策树 stump)串行地训练:每一轮根据前面模型的错误率调整样本权重,让后续弱学习器更“关注”被错分的样本。

最终加权投票得到强分类器。

换一个角度:指数损失的逐步最小化

AdaBoost 可以被看成在函数空间中做前向分步(forward stagewise)加法建模,目标是最小化指数损失

其中  是弱分类器(输出 )。

如何得到  与样本权重更新

第一,在第  步,已知 ,想选   使  减小最多,即最小化

 ,则问题变为最小化

第二,令  为在权重  下的加权错误率:

  固定,关于  求导并令导数为 0,可得(经典结果):

第三,更新样本权重(归一化):

或等价地错分样本权重会放大,正确分类样本权重会缩小(按 )。

归一化常数  保证  和为 1:

AdaBoost = 前向逐步拟合指数损失,对噪声敏感,因为指数损失对错分点的惩罚非常高,含噪数据或标签错误会被不断放大权重,从而可能导致过拟合。

弱学习器要求,只要每轮的弱学习器的加权错误率 < 0.5,AdaBoost 就能产生强分类器(理论上错误率指数下降)。

并行化差,每一轮依赖前一轮的权重,天然串行。


GBDT

把模型表示为加法模型:

每一步根据当前模型残差(即目标函数对当前预测的负梯度)去拟合一个新树 ,然后用线搜索找到最优步长 

换句话说,是在函数空间做梯度下降:每一步都沿着损失函数的负梯度方向增加一个基学习器。

GBDT 的强大之处在于:可以针对任意可微损失函数(回归的 MSE、分类的对数损失等)使用同样思想。

关键公式

目标:最小化总体损失

初始化 (例如常数预测,最小化总体损失的常数):

对于 

  1. 计算负梯度(pseudo-residuals):
  1. 拟合一个回归树 (通常用平方误差)去拟合 ,即最小化
  1. 对每个叶子做线搜索(或对于整棵树做一次步长确定),找到最优叶子输出 (若树有 J 片叶),常用的做法是对每个叶 (落在该叶的样本集合)计算
  1. 更新模型:

其中  学习率(shrinkage),帮助正则化(小  更稳健,但需增大树的数量 )。

三者数学层面比较

模型形式

  • Random Forest: 平均(bagging)

  • AdaBoost: ,通过权重  加权投票。目标等价于最小化指数损失。

  • GBDT: ,每一步拟合损失的负梯度(通用损失)。

损失函数

  • RF:每棵树独立生长,树的分裂局部优化(如 MSE 或 Gini),整体没有直接全局损失函数被显式最小化(ensemble 是平均/投票)。

  • AdaBoost:全局损失是 指数损失 

  • GBDT:直接最小化任意可微损失 ,用梯度步骤近似。

训练方式与并行性

  • RF:每棵树相互独立 → 高度并行

  • AdaBoost:轮间依赖权重 → 串行

  • GBDT:序列地拟合残差 → 串行(但可以用近似并行技巧)

对噪声/离群值的敏感性

  • RF:相对稳健,对噪声不太敏感(因为平均能抵消)。

  • AdaBoost:敏感(指数损失对离群点惩罚大)。

  • GBDT:取决于损失函数,使用对数损失或 Huber 等可更稳健。

偏差-方差

  • RF:主要目标是降低方差,某程度会略微增加偏差。

  • Boosting(AdaBoost/GBDT):通过串行纠错倾向于降低偏差,但可能增加过拟合(特别是 AdaBoost 在噪声下)。

  • GBDT 通过 shrinkage、subsampling、树限制等来控制过拟合。

总的来说,三者都不如单棵浅树直观,但 GBDT(尤其浅树 + 特征重要性 + SHAP)在工业里可解释性/贡献度分析工具更多。RF 也常用于特征重要性排序。

完整案例

我们生成一个带噪声的二维分类数据集,让三种模型去分类。

我们比较:

  • 模型的决策边界(是否平滑 / 是否过拟合)
  • 在不同训练样本数下的性能变化(学习曲线)
  • 特征重要性的不同分布(模型解释性差异)
  • 对噪声样本的敏感程度(鲁棒性)

完整代码实现:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split, learning_curve
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.metrics import accuracy_score
import seaborn as sns

# 1. 数据集
X, y = make_moons(n_samples=1000, noise=0.3, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 2. 定义三种模型
rf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
ada = AdaBoostClassifier(n_estimators=100, learning_rate=0.5, random_state=42)
gbdt = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

models = {
    "Random Forest": rf,
    "AdaBoost": ada,
    "GBDT": gbdt
}

# 3. 拟合模型并收集预测结果
for name, model in models.items():
    model.fit(X_train, y_train)

# 准备绘制图像
fig, axes = plt.subplots(22, figsize=(1512))
plt.subplots_adjust(hspace=0.3, wspace=0.3)
cmap = plt.cm.rainbow  # 鲜艳调色板

# 4. 图1:决策边界可视化
ax = axes[00]
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 300),
                     np.linspace(y_min, y_max, 300))

for name, model in models.items():
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
    ax.contourf(xx, yy, Z, alpha=0.2, cmap=cmap)
    ax.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cmap, edgecolor='k', s=30, label=name)

ax.set_title("Decision Boundaries Comparison", fontsize=15)
ax.legend()
ax.set_xlabel("Feature 1")
ax.set_ylabel("Feature 2")

# 5. 图2:学习曲线(训练/测试准确率随样本数变化)
ax = axes[01]
for name, model in models.items():
    train_sizes, train_scores, test_scores = learning_curve(model, X, y, cv=5,
                                                            train_sizes=np.linspace(0.11.08),
                                                            scoring="accuracy", n_jobs=-1)
    train_mean = train_scores.mean(axis=1)
    test_mean = test_scores.mean(axis=1)
    ax.plot(train_sizes, train_mean, 'o-', label=f"{name} Train", alpha=0.8)
    ax.plot(train_sizes, test_mean, '^-', label=f"{name} Test", alpha=0.8)
ax.set_title("Learning Curves", fontsize=15)
ax.set_xlabel("Training Samples")
ax.set_ylabel("Accuracy")
ax.legend()

# 6. 图3:特征重要性比较
ax = axes[10]
importances = np.array([m.feature_importances_ for m in models.values()])
sns.barplot(x=["Feature 1""Feature 2"],
            y=importances.mean(axis=0),
            palette="rainbow", ax=ax)
ax.set_title("Average Feature Importance", fontsize=15)
ax.set_ylabel("Importance")

# 7. 图4:对噪声的鲁棒性(添加不同噪声,测测试准确率)
ax = axes[11]
noises = np.linspace(0.00.58)
acc_results = {name: [] for name in models}
for noise in noises:
    Xn, yn = make_moons(n_samples=600, noise=noise, random_state=42)
    Xn_train, Xn_test, yn_train, yn_test = train_test_split(Xn, yn, test_size=0.3, random_state=42)
    for name, model in models.items():
        model.fit(Xn_train, yn_train)
        acc_results[name].append(accuracy_score(yn_test, model.predict(Xn_test)))

for name, acc in acc_results.items():
    ax.plot(noises, acc, 'o-', label=name, linewidth=2)
ax.set_title("Noise Robustness Test", fontsize=15)
ax.set_xlabel("Noise Level")
ax.set_ylabel("Test Accuracy")
ax.legend()

plt.suptitle("Random Forest vs AdaBoost vs GBDT — Systematic Comparison", fontsize=18, fontweight='bold')
plt.show()
通透!随机森林、AdaBoost、GBDT 对比 !!图1
  1. 决策边界:随机森林边界平滑且稳定,AdaBoost容易追噪声过拟合,GBDT平衡了偏差与方差。
  2. 学习曲线:随机森林泛化稳定,AdaBoost训练高但易过拟合,GBDT整体精度最高且随样本增加持续提升。
  3. 特征重要性:所有模型识别关键特征,但AdaBoost权重偏极端,GBDT和RF估计更稳健。
  4. 噪声鲁棒性:随机森林最抗噪声,GBDT次之,AdaBoost最敏感。

总结对比结论

算法
优势
劣势
适用场景
随机森林
并行高效,抗噪声强,调参少
模型解释性差,输出难微调
快速 baseline,特征多样的结构化数据
AdaBoost
理论简单,适合干净数据
对噪声敏感,串行慢
样本干净、小规模问题
GBDT
高精度,可用多种损失,灵活性强
串行训练慢,调参多
工业界主力模型(结构化数据)

总的来说,随机森林稳定且抗噪声,AdaBoost敏感易过拟合,GBDT兼顾高精度与稳健性,是三者在偏差、方差和鲁棒性上的典型取舍。

最后

最近准备了,完整的机器学习小册,免费领取~
通透!随机森林、AdaBoost、GBDT 对比 !!图2
领取:备注「算法小册」即可~
通透!随机森林、AdaBoost、GBDT 对比 !!图3
扫码如有问题,记得添加微信号:xiaobai_ml012