之前做了不少算法在不同情况下的对比,今天想要和大家聊聊的是关于 GBDT 与 LightGBM 的内容~
首先咱们从简单的一个介绍开始,GBDT 和 LightGBM 都属于梯度提升树 模型,它们是集成学习中的一种方法,通过构建多个弱学习器(通常是决策树)来提升整体的预测效果。
这两者的核心思想是:每棵新树都在减少之前模型的误差,最终形成一个强大的模型。
GBDT :
GBDT通过多棵树的梯度加权提升来减少误差。其优点是高精度和较好的泛化能力,但缺点是训练速度较慢,尤其在处理大数据时。
LightGBM :
LightGBM是GBDT的改进版本,通过优化树的构建过程,采用基于直方图的方法和叶子增长策略来大幅加速训练,同时降低内存消耗,因此更适合大规模数据和高维度问题。
核心原理 GBDT 原理 GBDT是一种集成学习算法,它使用多个决策树模型的加权组合来做预测。GBDT通过「梯度下降」来不断减少模型误差,以构建每一轮的树。在每一步,GBDT构建一个新的决策树,以当前模型的残差作为目标变量,逐步改进预测结果。
核心公式与解释 在GBDT中,每棵树都是在上一个模型的基础上学习残差。假设训练数据为
,我们要训练一个模型 以拟合目标 。
初始模型 :
设初始模型
为常数模型(例如,均值),即:
其中 是损失函数。
迭代更新 :
通过迭代构造新的决策树模型来更新 。在第 轮,构建一个决策树来拟合上一次预测的残差,即:
然后,利用残差
来训练第 棵树,以生成新的预测模型 。
模型更新 :
更新模型为:
其中 是学习率,用于控制每棵树的贡献。
算法流程 初始化模型 :设定初始预测模型。
迭代构建树 :
模型输出 :迭代完成后输出最终模型。
优缺点 优点 :
适合非线性问题:基于树的模型能处理复杂的非线性关系。 缺点 :
难以并行化:传统GBDT构建每棵树都依赖上一棵树的结果,因而难以进行并行化计算。 适用场景 适合 :中小规模数据集、特征维度不特别高的情况。
不适合 :数据量大且特征维度高的场景(在这种场景下性能较差,通常选择优化的LightGBM等算法)。
LightGBM 原理 LightGBM是基于GBDT的优化算法,目标是提高GBDT在大规模数据和高维特征下的性能。LightGBM使用了基于直方图的决策树算法,同时引入了多项优化技术如叶子增长策略等,从而大幅提升了计算效率。
核心公式与解释 LightGBM的核心优化集中在构建决策树的过程上,它使用了基于直方图的方法来计算分裂节点,从而加速训练过程:
直方图算法 :
将特征值离散化,分箱到直方图中,每个箱子代表一个特征值区间。这样在计算分裂时,只需计算箱子的分裂增益,而不是每个数据点,极大地减少了计算量。
叶子增长策略(Leaf-wise Growth) :
与传统GBDT使用按层增长不同,LightGBM选择叶子增长策略,即在每次分裂时选择最能降低误差的叶子节点进行分裂,从而使得每次分裂都能最大限度地提升模型效果。
算法流程 特征值分箱
:将连续特征值离散化到直方图。
迭代构建树 :
每轮迭代中,从当前叶子中选择误差下降最多的叶子节点进行分裂。 更新模型 :将新树的预测值加入当前模型。
输出模型 :迭代完成后输出最终模型。
优缺点 优点 :
缺点 :
使用叶子增长策略可能导致不平衡的树结构,使模型的泛化能力下降。 适用场景 适合 :大规模数据集、特征维度高的场景,特别是训练时间和资源消耗较多的任务。
不适合 :数据量较小、对过拟合敏感的场景。
总结对比 特性 GBDT
LightGBM 核心思想 迭代构建决策树,拟合残差 基于直方图的快速GBDT 树构建策略 按层生长(Level-wise) 按叶子生长(Leaf-wise) 并行化 较难 支持 适用数据 中小规模数据 大规模数据,高维特征 优点 模型灵活,能处理非线性关系 训练快,资源使用低,适合高维和大数据 缺点 训练时间长,难并行 过拟合风险高,特别在小数据集
在实际应用中,一般来说,如果数据量较小且不需要特别快的训练速度,可以优先选择GBDT;而对于大数据场景,LightGBM则会提供显著的效率优势。
完整案例 问题描述 :假设我们有一个分类任务,需要预测用户是否会进行某项购买行为。数据集中包含用户的浏览记录、兴趣偏好、购买习惯等多维特征。目标是通过模型预测购买概率,从而实现个性化推荐。
目标 :比较GBDT与LightGBM在虚拟数据集上的性能与适用性。我们将通过准确率、训练时间和资源消耗等指标进行详细分析,并使用绘图直观地展示结果。
我们这里,使用虚拟数据生成一组多维分类数据,包括数值型和类别型特征。数据样本包含10000行,每行10个特征,其中5个为数值型,5个为类别型,目标变量是一个二分类标记。
import numpy as npimport pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import accuracy_score, roc_auc_scorefrom sklearn.datasets import make_classificationfrom sklearn.ensemble import GradientBoostingClassifierimport lightgbm as lgbimport timeimport matplotlib.pyplot as pltimport seaborn as sns# 设置随机种子以便复现 np.random.seed(42 )# 生成虚拟分类数据集
X, y = make_classification(n_samples=10000 , n_features=10 , n_informative=6 , n_redundant=2 , n_classes=2 , random_state=42 )# 转换为DataFrame格式并模拟类别型特征 X = pd.DataFrame(X, columns=[f"feature_{i} " for i in range(10 )])for i in range(5 , 10 ): # 将部分特征设为类别型 X[f'feature_{i} ' ] = pd.cut(X[f'feature_{i} ' ], bins=4 , labels=[0 , 1 , 2 , 3 ])# 分割训练集与测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3 , random_state=42 )
模型训练与评估 1. 使用GBDT进行训练
# 初始化GBDT模型 gbdt_model = GradientBoostingClassifier(n_estimators=100 , learning_rate=0.1 , max_depth=3 , random_state=42 )# 记录训练时间 start_time = time.time() gbdt_model.fit(X_train, y_train) gbdt_train_time = time.time() - start_time# 评估GBDT模型 y_pred_gbdt = gbdt_model.predict(X_test) y_proba_gbdt = gbdt_model.predict_proba(X_test)[:, 1 ] gbdt_accuracy = accuracy_score(y_test, y_pred_gbdt) gbdt_auc = roc_auc_score(y_test, y_proba_gbdt) print(f"GBDT Accuracy: {gbdt_accuracy:.4 f} " ) print(f"GBDT AUC: {gbdt_auc:.4 f} " ) print(f"GBDT Training Time: {gbdt_train_time:.4 f} seconds" )
2. 使用LightGBM进行训练
# 准备LightGBM数据集 train_data = lgb.Dataset(X_train, label=y_train, categorical_feature=[f'feature_{i} ' for i in range(5 , 10 )]) test_data = lgb.Dataset(X_test, label=y_test, categorical_feature=[f'feature_{i} ' for i in range(5 , 10 )], reference=train_data)# 设置参数 lgb_params = { 'objective' : 'binary' , 'boosting_type' : 'gbdt' , 'metric' : ['auc' ], 'num_leaves' : 31 , 'learning_rate' : 0.1 , 'verbose' : -1 }
# 记录训练时间 start_time = time.time() lgb_model = lgb.train(lgb_params, train_data, valid_sets=[test_data], num_boost_round=100 , early_stopping_rounds=10 , verbose_eval=False ) lgb_train_time = time.time() - start_time# 评估LightGBM模型 y_proba_lgb = lgb_model.predict(X_test) y_pred_lgb = (y_proba_lgb >= 0.5 ).astype(int) lgb_accuracy = accuracy_score(y_test, y_pred_lgb) lgb_auc = roc_auc_score(y_test, y_proba_lgb) print(f"LightGBM Accuracy: {lgb_accuracy:.4 f} " ) print(f"LightGBM AUC: {lgb_auc:.4 f} " ) print(f"LightGBM Training Time: {lgb_train_time:.4 f} seconds" )
性能与适用性分析 我们将绘制以下三张图来帮助大家进行对比分析:
1. 训练时间对比 :展示GBDT与LightGBM的训练时间差异。
2. 模型准确率对比 :比较GBDT与LightGBM的准确率,衡量二者在测试集上的表现。
3. AUC对比 :展示两种模型在测试集上的AUC评分,以反映其预测的稳健性。
# 绘制图形 fig, axes = plt.subplots(1 , 3 , figsize=(18 , 6 ))# 图1:训练时间对比 sns.barplot(x=['GBDT' , 'LightGBM' ], y=[gbdt_train_time, lgb_train_time], ax=axes[0 ], palette="viridis" ) axes[0 ].set_title('Training Time Comparison' ) axes[0 ].set_ylabel('Training Time (seconds)' )# 图2:模型准确率对比 sns.barplot(x=['GBDT' , 'LightGBM' ], y=[gbdt_accuracy, lgb_accuracy], ax=axes[1 ], palette="viridis" ) axes[1 ].set_title('Accuracy Comparison' ) axes[1 ].set_ylabel('Accuracy' )# 图3:AUC对比 sns.barplot(x=['GBDT' , 'LightGBM' ], y=[gbdt_auc, lgb_auc], ax=axes[2 ], palette="viridis" ) axes[2 ].set_title('AUC Score Comparison' ) axes[2 ].set_ylabel('AUC Score' ) plt.tight_layout() plt.show()
从上图我们可以看到:
1. 训练时间 :LightGBM显著快于GBDT,表明在大数据集场景下LightGBM在训练效率上具有明显优势。
2. 准确率 :在准确率方面,LightGBM与GBDT表现接近,LightGBM稍有优势,符合大数据环境下的预期表现。
3. AUC :两种模型在AUC上差异不大,LightGBM略高。
在本案例中,LightGBM在大数据集下显著提升了训练速度,同时保持了良好的准确率和AUC评分。通过选择LightGBM,模型可以在更短时间内实现同等甚至更优的预测效果,因此在实际应用中更适合用于大规模数据和高维特征的场景。
调参细节 参数调节方面,大家可以参考以下方式进行~
GBDT 调参 :
n_estimators
:调整为100,控制树的数量。learning_rate
:设为0.1,平衡模型复杂性与训练时间。LightGBM 调参 :
num_leaves
:设为31,控制单棵树的复杂度。learning_rate
:设为0.1,与GBDT一致。early_stopping_rounds
:设为10,防止模型过拟合并加速训练。