所有文章 > AI驱动 > 选择最佳模型,轻松上手 GBDT、LightGBM、XGBoost、AdaBoost !!

选择最佳模型,轻松上手 GBDT、LightGBM、XGBoost、AdaBoost !!

GBDT、LightGBM、XGBoost 和 AdaBoost 都属于提升树 (Boosting) 算法。它们通过逐步训练一系列弱学习器(通常是决策树),并将这些弱学习器组合成一个强学习器,以提高模型的准确性。其主要优势包括对复杂数据结构的建模能力强、较高的预测精度以及能够处理缺失值和非线性关系。相比之下,LightGBM 和 XGBoost 在计算效率和内存利用上有显著提升,适合大规模数据处理。

那下面,咱们一起来具体看看各个算法,也进行一个比较~

GBDT(Gradient Boosting Decision Tree)

原理

GBDT(梯度提升决策树)是通过构建一系列决策树,逐步减少模型的误差。每棵树都是在前一棵树的残差基础上构建的。

核心公式和解释

算法流程

优缺点

优点:

  • 强大的预测性能。
  • 能处理非线性问题。
  • 灵活,适用于回归和分类问题。

缺点:

  • 训练时间较长。
  • 对参数调优敏感。
  • 难以并行化。

适用场景

  • 回归任务,如房价预测。
  • 分类任务,如垃圾邮件检测。
  • 排序任务,如搜索引擎结果排序。

LightGBM

原理

LightGBM 是一种高效的梯度提升框架,专注于快速训练和低内存使用。它采用了基于直方图的决策树学习算法,显著提高了效率。

核心公式和解释

LightGBM 的核心与 GBDT 相同,但在优化方面进行了改进。它引入了基于直方图的算法,将连续值离散化,从而加快了训练速度并降低了内存消耗。

算法流程

  1. 构建特征直方图。
  2. 计算每个特征的增益,选择增益最大的特征进行分裂。
  3. 基于直方图的累积直方图法快速计算最佳分割点。
  4. 构建决策树,更新模型。

优缺点

优点:

  • 训练速度快。
  • 内存效率高。
  • 支持并行学习。
  • 能处理大规模数据。

缺点:

  • 对于小数据集性能提升不明显。
  • 参数较多,调优复杂。

适用场景

  • 大规模数据集的分类和回归任务。
  • 实时在线学习任务。

XGBoost

原理

XGBoost 是一种高效的梯度提升框架,优化了传统的 GBDT,并引入了正则化项以防止过拟合。

核心公式和解释

算法流程

  1. 初始化模型。
  2. 对每一轮迭代:
  3. 1. 计算当前模型的残差。
  4. 根据残差拟合新的树。
  5. 计算正则化项并更新模型。
  6. 输出最终模型。

优缺点

优点:

  • 强大的预测性能。
  • 控制过拟合的能力强。
  • 并行计算支持良好。
  • 易于集成和调优。

缺点:

  • 对内存要求较高。
  • 参数调优较复杂。

适用场景

  • 各种分类和回归任务。
  • 大数据处理,如Kaggle竞赛。

AdaBoost

原理

AdaBoost(Adaptive Boosting)通过结合多个弱分类器来提高分类性能。每个分类器的权重由其错误率决定,后续分类器更关注前面分类器错误分类的样本。

核心公式和解释

算法流程

  1. 初始化样本权重。
  2. 对每个弱分类器:
  3. 1. 训练分类器,计算分类误差。
  4. 根据误差计算分类器权重。
  5. 更新样本权重。
  6. 最终分类器为所有弱分类器的加权和。

优缺点

优点:

  • 简单易实现。
  • 强大的集成学习效果。
  • 能提高弱分类器的性能。

缺点:

  • 对噪声数据敏感。
  • 不能并行训练。

适用场景

综合案例

这里,咱们是一个使用 GBDT、LightGBM、XGBoost 和 AdaBoost 的完整示例。

整个这个示例将涵盖以下内容:

  1. 数据准备:生成一个简单的合成数据集。
  2. 模型训练和预测:训练四种不同的模型。
  3. 性能比较:比较每个模型的性能。
  4. 可视化:展示每个模型的预测结果和性能。

我们将使用以下包:

  • scikit-learn:用于 GBDT 和 AdaBoost。
  • lightgbm:用于 LightGBM。
  • xgboost:用于 XGBoost。
  • matplotlibseaborn:用于数据可视化

数据准备

我们将生成一个合成的回归数据集,以便比较不同模型的性能。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import lightgbm as lgb
import xgboost as xgb
from sklearn.ensemble import GradientBoostingRegressor, AdaBoostRegressor
from sklearn.tree import DecisionTreeRegressor

# 生成合成数据
X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 转换为 DataFrame 以便绘图
df_train = pd.DataFrame(X_train, columns=[f"feature_{i}" for i in range(X_train.shape[1])])
df_train['target'] = y_train
df_test = pd.DataFrame(X_test, columns=[f"feature_{i}" for i in range(X_test.shape[1])])
df_test['target'] = y_test

训练模型并进行预测

# 1. Gradient Boosting Decision Tree (GBDT)
gbdt_model = GradientBoostingRegressor(n_estimators=100, random_state=42)
gbdt_model.fit(X_train, y_train)
y_pred_gbdt = gbdt_model.predict(X_test)

# 2. LightGBM
lgb_model = lgb.LGBMRegressor(n_estimators=100, random_state=42)
lgb_model.fit(X_train, y_train)
y_pred_lgb = lgb_model.predict(X_test)

# 3. XGBoost
xgb_model = xgb.XGBRegressor(n_estimators=100, random_state=42)
xgb_model.fit(X_train, y_train)
y_pred_xgb = xgb_model.predict(X_test)

# 4. AdaBoost
ada_model = AdaBoostRegressor(base_estimator=DecisionTreeRegressor(max_depth=3), n_estimators=100, random_state=42)
ada_model.fit(X_train, y_train)
y_pred_ada = ada_model.predict(X_test)

性能评估

def evaluate_model(y_true, y_pred, model_name):
mse = mean_squared_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)
print(f"{model_name} - MSE: {mse:.4f}, R2: {r2:.4f}")

print("Performance Comparison:")
evaluate_model(y_test, y_pred_gbdt, "GBDT")
evaluate_model(y_test, y_pred_lgb, "LightGBM")
evaluate_model(y_test, y_pred_xgb, "XGBoost")
evaluate_model(y_test, y_pred_ada, "AdaBoost")

可视化

我们将绘制模型的预测结果与实际值的对比图,并绘制预测值的分布图。

plt.style.use('ggplot')  # 使用有效的样式
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
axes = axes.flatten()

def plot_predictions(ax, y_true, y_pred, model_name):
sns.scatterplot(x=y_true, y=y_pred, ax=ax)
ax.plot([min(y_true), max(y_true)], [min(y_true), max(y_true)], 'k--', label='Perfect Prediction')
ax.set_title(f'{model_name} Predictions vs Actual')
ax.set_xlabel('Actual Values')
ax.set_ylabel('Predicted Values')
ax.legend()

# 预测与实际值对比
plot_predictions(axes[0], y_test, y_pred_gbdt, 'GBDT')
plot_predictions(axes[1], y_test, y_pred_lgb, 'LightGBM')
plot_predictions(axes[2], y_test, y_pred_xgb, 'XGBoost')
plot_predictions(axes[3], y_test, y_pred_ada, 'AdaBoost')

plt.tight_layout()
plt.show()

# 预测值分布图
fig, axes = plt.subplots(2, 2, figsize=(16, 12))
axes = axes.flatten()

def plot_prediction_distribution(ax, y_pred, model_name):
sns.histplot(y_pred, ax=ax, kde=True, bins=30)
ax.set_title(f'{model_name} Predicted Values Distribution')
ax.set_xlabel('Predicted Values')
ax.set_ylabel('Frequency')

# 绘制预测值的分布
plot_prediction_distribution(axes[0], y_pred_gbdt, 'GBDT')
plot_prediction_distribution(axes[1], y_pred_lgb, 'LightGBM')
plot_prediction_distribution(axes[2], y_pred_xgb, 'XGBoost')
plot_prediction_distribution(axes[3], y_pred_ada, 'AdaBoost')

plt.tight_layout()
plt.show()

可视化部分:

预测与实际值对比:

预测值分布图:

适用性和性能比较

  1. GBDT
  2. 适用性:通用的梯度提升算法,适用于各种回归和分类任务。
  • 性能:通常表现良好,但对大数据集可能较慢。
  1. LightGBM
  2. 适用性:高效的梯度提升算法,专为大规模数据和高维特征设计。
  • 性能:在速度和内存使用上优于传统的 GBDT,特别是在大数据集上。
  1. XGBoost
  2. 适用性:优化的梯度提升算法,具有强大的性能和灵活性。
  • 性能:速度较快,性能优越,但调参可能较复杂。
  1. AdaBoost
  2. 适用性:提升算法的简单实现,适合于少量样本或简单问题。
  • 性能:可能不如 GBDT 或 LightGBM 强大,但简单且易于理解。

调参细节

针对 GBDT、LightGBM、XGBoost 和 AdaBoost 的调参细节以及每种方法的建议参数范围和优化技巧。

1. Gradient Boosting Decision Tree (GBDT)

GBDT 通常使用 sklearnGradientBoostingRegressor 来实现。主要调参项包括:

  • n_estimators: 树的数量。增加数量可以提高模型的性能,但会增加计算时间和可能导致过拟合。推荐范围:1001000
  • learning_rate: 学习率。控制每棵树对最终预测的贡献。较小的学习率可以提高模型的性能,但需要更多的树。推荐范围:0.010.2
  • max_depth: 每棵树的最大深度。限制树的深度可以防止过拟合。推荐范围:310
  • min_samples_split: 每个内部节点的最小样本数,用于进行分裂。增加此值可以防止过拟合。推荐范围:220
  • min_samples_leaf: 每个叶子节点的最小样本数。增加此值也可以防止过拟合。推荐范围:120
  • subsample: 每棵树训练时使用的样本比例。推荐范围:0.51.0

调参技巧

  • 使用网格搜索(GridSearchCV)或随机搜索(RandomizedSearchCV)来寻找最佳超参数。
  • 首先固定 n_estimators 的值,调整 learning_ratemax_depth,然后调整其他参数。

2.LightGBM

LightGBM 是一个高效的梯度提升框架,适用于大规模数据。主要调参项包括:

  • num_leaves: 每棵树的叶子数量。更多的叶子可能导致过拟合。推荐范围:20300
  • learning_rate: 学习率。较小的学习率与更多的树结合使用。推荐范围:0.010.2
  • n_estimators: 树的数量。推荐范围:1001000
  • max_depth: 树的最大深度。推荐范围:-1(无限制)到 20
  • min_child_samples: 每个叶子上的最小样本数。推荐范围:10100
  • subsample: 训练样本的比例。推荐范围:0.51.0
  • colsample_bytree: 每棵树的特征比例。推荐范围:0.51.0

调参技巧

  • LightGBM 支持通过交叉验证(lgb.cv)来选择最佳超参数。
  • 可以通过 optuna 等库来进行超参数优化。

3. XGBoost

XGBoost 是另一种流行的梯度提升框架。主要调参项包括:

  • n_estimators: 树的数量。推荐范围:1001000
  • learning_rate: 学习率。推荐范围:0.010.2
  • max_depth: 树的最大深度。推荐范围:310
  • min_child_weight: 每个叶子节点的最小样本权重。推荐范围:110
  • subsample: 训练样本的比例。推荐范围:0.51.0
  • colsample_bytree: 每棵树的特征比例。推荐范围:0.51.0
  • gamma: 节点分裂所需的最小损失函数下降值。推荐范围:05

调参技巧

  • XGBoost 提供了交叉验证功能(xgb.cv)来选择最佳超参数。
  • 使用 GridSearchCVRandomizedSearchCV 来找到最佳参数组合。

4. AdaBoost

AdaBoost 是一种提升方法,通过调整每个样本的权重来提高模型性能。主要调参项包括:

  • n_estimators: 基学习器的数量。推荐范围:50500
  • learning_rate: 学习率。控制每个基学习器的贡献。推荐范围:0.011.0
  • base_estimator: 基学习器。常用的基学习器是 DecisionTreeRegressor,可以设置其参数,如 max_depth

调参技巧

  • 尝试不同数量的基学习器和学习率组合。
  • 基学习器的复杂度(例如 DecisionTreeRegressormax_depth)会影响模型性能,适当调整。

代码中的调参示例

假设我们使用网格搜索来调整 GBDT 的超参数:

from sklearn.model_selection import GridSearchCV

# 定义参数网格
param_grid = {
'n_estimators': [100, 200, 300],
'learning_rate': [0.01, 0.1, 0.2],
'max_depth': [3, 5, 7],
'min_samples_split': [2, 5, 10],
'min_samples_leaf': [1, 2, 5]
}

# 创建模型
gbdt = GradientBoostingRegressor()

# 使用网格搜索进行调参
grid_search = GridSearchCV(estimator=gbdt, param_grid=param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)

# 输出最佳参数
print("Best parameters found: ", grid_search.best_params_)

大家可以对 LightGBM 和 XGBoost 进行类似的调参,只需使用相应的模型和参数网格。

调参是一个迭代的过程,通常需要多次实验才能找到最佳参数组合。希望这些细节和技巧能帮助大家在自己实际的实验中,可以得到一些启发!~

文章转自微信公众号@深夜努力写Python