第二章:LightGBM 核心原理


文档摘要

第二章:LightGBM 核心原理 第二章:LightGBM 核心原理 2.1 引言:GBDT 的进化与 LightGBM 的诞生 梯度提升决策树 (Gradient Boosting Decision Tree, GBDT) 作为一种强大的机器学习算法,在分类和回归任务中表现出色。它通过迭代地训练一系列决策树,并将这些弱学习器组合成一个强大的集成模型。然而,传统的 GBDT 算法在处理大规模数据和高维度特征时,效率和可扩展性面临挑战。 为了解决这些问题,并进一步提升 GBDT 的性能,微软在 2017 年推出了 LightGBM (Light Gradient Boosting Machine)。

第二章:LightGBM 核心原理

第二章:LightGBM 核心原理

2.1 引言:GBDT 的进化与 LightGBM 的诞生

梯度提升决策树 (Gradient Boosting Decision Tree, GBDT) 作为一种强大的机器学习算法,在分类和回归任务中表现出色。它通过迭代地训练一系列决策树,并将这些弱学习器组合成一个强大的集成模型。然而,传统的 GBDT 算法在处理大规模数据和高维度特征时,效率和可扩展性面临挑战。

为了解决这些问题,并进一步提升 GBDT 的性能,微软在 2017 年推出了 LightGBM (Light Gradient Boosting Machine)。LightGBM 继承了 GBDT 的核心思想,并在算法层面进行了多项创新性的优化,使其在保持高精度的同时,显著提升了训练速度和内存效率。

LightGBM 的核心优势:

  • 更快的训练速度和更高的效率: LightGBM 使用了多种技术来加速训练过程,例如梯度单边采样 (GOSS) 和互斥特征捆绑 (EFB)。

  • 更低的内存消耗: 通过使用直方图算法和特征捆绑等技术,LightGBM 显著降低了内存占用。

  • 更高的准确率 (在某些情况下): Leaf-wise (叶子生长) 的树生长策略使得 LightGBM 可以生成更深更复杂的树模型,从而可能获得更高的精度。

  • 支持大规模数据和高维度特征: LightGBM 的优化使其能够高效处理海量数据和高维度特征,适用于现代大数据场景。

  • 支持并行和 GPU 学习: LightGBM 支持特征并行和数据并行,并可利用 GPU 进行加速,进一步提升训练效率。

本章将深入探讨 LightGBM 的核心原理,详细解释其关键技术,并通过代码实践加深理解。

2.2 GBDT 的基础:回顾梯度提升决策树

为了更好地理解 LightGBM 的创新之处,我们首先回顾一下 GBDT 的基本原理。GBDT 是一种集成学习算法,它通过迭代地训练一系列弱学习器(通常是决策树)来构建一个强学习器。其核心思想是 梯度提升 (Gradient Boosting)。

GBDT 的基本流程:

  1. 初始化弱学习器: 通常使用一个简单的模型,例如常数模型,作为初始的弱学习器 f_0(x)

  2. 迭代训练弱学习器: 进行 M 轮迭代 (M 是弱学习器的数量):

    • 计算负梯度 (残差): 对于第 m 轮迭代,计算损失函数 L(y_i, F_{m-1}(x_i)) 在每个样本 x_i 上的负梯度,作为残差的近似值:

      {im} = -\left[ \frac{\partial L(y_i, F(x_i))}{\partial F(x_i)} \right]_{F(x) = F_{m-1}(x)}

      其中,F_{m-1}(x) 是前 m-1 轮迭代得到的集成模型。

    • 训练弱学习器: 使用残差 r_{im} 作为新的目标值,训练一个新的决策树 h_m(x)

    • 计算弱学习器的权重: 通过线性搜索或其他优化方法,找到最佳的步长 \rho_m,使得损失函数最小化:

      ho_m = \mathop{\arg\min}_{\rho} \sum_{i=1}^{n} L(y_i, F_{m-1}(x_i) + \rho h_m(x_i))
    • 更新集成模型: 将新的弱学习器 h_m(x) 加入到集成模型中:

      m(x) = F_{m-1}(x) + \rho_m h_m(x)
  3. 得到最终模型: 经过 M 轮迭代后,得到最终的集成模型 F_M(x) = \sum_{m=1}^{M} \rho_m h_m(x)

GBDT 的关键特点:

  • 加法模型: GBDT 是一个加法模型,通过将多个弱学习器线性组合起来。

  • 前向分步算法: GBDT 使用前向分步算法,每一步只学习一个新的弱学习器。

  • 负梯度拟合: GBDT 通过拟合损失函数的负梯度 (残差) 来逼近真实值。

  • 可灵活选择损失函数: GBDT 可以根据不同的任务选择不同的损失函数,例如平方误差损失 (回归)、对数损失 (二分类)、多分类损失 (多分类) 等。

GBDT 的局限性:

  • 训练速度慢: 尤其是当数据量和特征维度较大时,GBDT 的训练速度会显著下降。

  • 容易过拟合: 当树的深度过深或弱学习器数量过多时,GBDT 容易过拟合。

  • 内存消耗大: 传统的 GBDT 算法在处理海量数据时,需要消耗大量的内存。

LightGBM 正是为了克服这些局限性而诞生的,它在 GBDT 的基础上进行了多项创新性的改进。

2.3 LightGBM 的核心原理:创新与优化

LightGBM 的核心在于其对传统 GBDT 算法的创新性优化,主要体现在以下几个方面:

2.3.1 Gradient-based One-Side Sampling (GOSS) - 梯度单边采样

问题: 在传统的 GBDT 中,所有样本都会被用于计算梯度和构建决策树。当数据量很大时,这会非常耗时。然而,并非所有样本对梯度的贡献都是相同的。梯度小的样本通常已经被模型学习得很好,对模型的提升贡献较小。

GOSS 的思想: GOSS 旨在通过减少梯度小的数据样本的使用,从而加速训练过程,同时尽可能保证模型的精度。它保留梯度大的样本,并对梯度小的样本进行随机采样

GOSS 的算法流程:

  1. 根据梯度绝对值排序: 对所有训练样本按照其梯度的绝对值进行降序排序。

  2. 保留梯度大的样本: 选取梯度绝对值最大的前 a% 的样本 (例如,a=20%),称为 "大梯度样本集 A"。

  3. 随机采样梯度小的样本: 从剩余的 (1-a)% 的样本中,随机抽取 b% 的样本 (例如,b=10%),称为 "小梯度样本集 B"。

  4. 放大梯度小的样本: 为了补偿小梯度样本的损失,GOSS 对小梯度样本集 B 中的样本梯度进行放大,放大的倍数为 \frac{1-a}{b}

  5. 使用合并后的样本集训练: 将大梯度样本集 A 和放大后的小梯度样本集 B 合并,作为新的训练数据集,用于计算信息增益和构建决策树。

Mermaid 图示 GOSS 流程:

GOSS 的优势:

  • 加速训练: 通过减少样本数量,显著降低了计算梯度和构建树的开销。

  • 保持精度: 由于保留了梯度大的样本,并对小梯度样本进行了补偿,GOSS 可以在加速训练的同时,尽可能保持模型的精度。

  • 适用于梯度稀疏场景: GOSS 在梯度稀疏的场景下效果更佳,例如,当模型已经学习得比较好的时候,大部分样本的梯度会很小。

GOSS 的参数:

  • feature_fraction: 控制特征采样的比例,与 GOSS 无直接关系,但可以结合使用以进一步提升效率。

  • bagging_fraction: 控制数据采样的比例,可以与 GOSS 结合使用,但需要注意采样策略的冲突。

  • top_rate (a): 控制大梯度样本的比例。

  • other_rate (b): 控制小梯度样本的采样比例。

2.3.2 Exclusive Feature Bundling (EFB) - 互斥特征捆绑

问题: 在高维度稀疏数据中,很多特征是互斥的 (mutually exclusive),即在大部分情况下,它们不会同时取非零值。例如,在 one-hot 编码后的类别特征中,每个特征只代表一个类别,同一样本在这些特征中只有一个取值为 1,其余都为 0。对于这些互斥特征,可以将其捆绑成一个特征,从而减少特征维度,加速训练。

EFB 的思想: EFB 旨在通过捆绑互斥特征,减少特征数量,从而降低计算复杂度,加速训练,并减少内存消耗。

EFB 的算法流程:

  1. 构建特征冲突图: 构建一个无权图,图的节点是特征,如果两个特征不是互斥的 (即存在同时取非零值的样本),则在它们之间添加一条边。

  2. 图排序: 按照节点的度 (连接的边的数量) 对特征进行降序排序。度越高的特征,与其他特征的冲突越多,越晚捆绑。

  3. 特征捆绑: 遍历排序后的特征列表,对于每个特征,尝试将其捆绑到已有的捆绑包中。捆绑的条件是:

    • 该特征与捆绑包中的所有特征都是互斥的,或者

    • 将该特征加入捆绑包后,仍然能够保证捆绑包内的特征近似互斥 (通过引入一个小的冲突阈值)。

    • 如果无法捆绑到已有的捆绑包,则创建一个新的捆绑包。

  4. 合并特征值: 对于每个捆绑包,将捆绑包内的特征值进行合并。合并的方法通常是偏移量累加 (offset accumulation)。例如,如果有两个互斥特征 feature1 和 feature2,它们的取值范围分别是 [0, 10] 和 [0, 15],可以将 feature2 的取值加上偏移量 11 (feature1 的最大值 + 1),然后将 feature1 和 feature2 合并成一个新的特征。

Mermaid 图示 EFB 流程:

EFB 的优势:

  • 降维: 显著减少特征维度,尤其是在高维度稀疏数据中。

  • 加速训练: 降低了特征数量,减少了计算信息增益和分裂节点的开销。

  • 减少内存消耗: 减少了特征数量,降低了内存占用。

  • 保持精度: 在互斥特征场景下,EFB 可以有效地保持模型的精度。

EFB 的参数:

  • feature_fraction: 控制特征采样的比例,与 EFB 无直接关系,但可以结合使用以选择部分特征进行捆绑。

  • max_conflict_rate: 控制捆绑包内特征的最大冲突率,用于控制近似互斥的程度。

  • min_data_in_leaf: 叶节点最小数据量,可能会影响特征互斥性的判断。

2.3.3 Histogram-based Algorithm - 直方图算法

问题: 传统的 GBDT 算法 (例如,XGBoost) 在寻找最佳分裂点时,通常需要对特征值进行预排序 (pre-sorted) 或精确扫描 (exact greedy)。这两种方法都比较耗时和耗内存,尤其是在数据量很大时。

直方图算法的思想: 直方图算法旨在通过将连续特征值离散化到 bins (桶) 中,构建直方图,然后基于直方图来寻找最佳分裂点。这样可以大大减少分裂点查找的计算量,并降低内存消耗。

直方图算法的流程:

  1. 特征值离散化: 对于每个连续特征,将其值域划分为 k 个 bins (例如,k=256)。可以使用等频 (quantile) 或等宽 (equal-width) 划分。

  2. 构建直方图: 对于每个特征,遍历所有样本,统计每个 bin 内的样本梯度累加值和样本数量。构建特征的直方图,直方图包含 k 个 bin,每个 bin 记录了梯度累加值和样本数量。

  3. 基于直方图寻找最佳分裂点: 遍历直方图的 bins,计算不同分裂点的信息增益 (例如,Gini 系数、信息熵等)。最佳分裂点将特征值划分为两部分,使得分裂后的信息增益最大。

直方图算法的优势:

  • 加速训练: 将连续特征离散化,大大减少了分裂点查找的计算量。只需遍历 bins,而无需遍历所有特征值。

  • 降低内存消耗: 直方图只需要存储 k 个 bins 的统计信息,相比于预排序或存储所有特征值,显著降低了内存占用。

  • 可以进一步加速: LightGBM 还对直方图算法进行了优化,例如,通过差加速直方图 (difference histogram),进一步减少了计算量。

  • 正则化效果: 直方图算法在一定程度上具有正则化效果,可以防止过拟合,因为离散化过程相当于对特征进行了平滑处理。

直方图算法的参数:

  • max_bin: 控制直方图的最大 bin 数量,较小的 max_bin 可以加速训练,但可能降低精度。

  • min_data_in_bin: 每个 bin 的最小数据量,可以防止过拟合。

  • bin_construct_sample_cnt: 用于构建直方图的样本数量,可以加速直方图构建,但可能影响直方图的精度。

2.3.4 Leaf-wise (Best-First) Tree Growth - 叶子生长 (最佳优先) 策略

问题: 传统的 GBDT 算法通常使用 level-wise (层级生长) 的树生长策略,即每次分裂同一层的所有叶节点。Level-wise 生长策略简单易实现,但效率较低,因为它会平等对待同一层的所有叶节点,但实际上有些叶节点的增益很小,分裂的意义不大。

Leaf-wise 生长策略的思想: Leaf-wise 生长策略每次从当前所有叶节点中,选择分裂增益最大的叶节点进行分裂,如此循环。Leaf-wise 生长策略可以构建出更深更复杂的树模型,从而可能获得更高的精度。

Leaf-wise 生长策略的流程:

  1. 初始化树: 从根节点开始。

  2. 迭代分裂叶节点: 在每一轮迭代中,执行以下步骤:

    • 计算所有叶节点的分裂增益: 对于当前所有的叶节点,计算它们分裂后的信息增益。

    • 选择最佳叶节点: 选择分裂增益最大的叶节点。

    • 分裂叶节点: 对最佳叶节点进行分裂,生成新的叶节点。

    • 更新叶节点集合: 将新的叶节点加入到叶节点集合中,移除被分裂的叶节点。

  3. 停止分裂条件: 当满足停止分裂条件时 (例如,达到最大深度、叶节点样本数过少等),停止树的生长。

Mermaid 图示 Leaf-wise vs Level-wise 树生长:

Leaf-wise 生长策略的优势:

  • 更高精度: Leaf-wise 生长策略可以生成更深更复杂的树模型,更好地拟合数据,从而可能获得更高的精度。

  • 更有效利用资源: Leaf-wise 生长策略优先分裂增益大的叶节点,更有效地利用了计算资源。

Leaf-wise 生长策略的局限性:

  • 容易过拟合: Leaf-wise 生长策略生成的树模型更复杂,更容易过拟合。需要通过参数调优 (例如,num_leaves, max_depth, min_data_in_leaf) 来控制模型的复杂度,防止过拟合。

  • 深度可能不均衡: Leaf-wise 生长策略生成的树模型的深度可能不均衡,某些分支可能很深,而某些分支可能很浅。

Leaf-wise 生长策略的参数:

  • boosting_type: 需要设置为 gbdtdart 才能使用 Leaf-wise 生长策略 (默认值)。

  • num_leaves: 控制树模型的复杂度,限制叶节点的最大数量。

  • max_depth: 限制树的最大深度,防止过拟合。

  • min_data_in_leaf: 叶节点最小数据量,防止叶节点过小,可以防止过拟合。

2.3.5 Network Communication Optimization (For Parallel Learning) - 网络通信优化 (并行学习)

LightGBM 为了支持高效的并行学习 (特征并行和数据并行),在网络通信方面也进行了优化。这部分内容相对底层,更偏向于系统实现层面,这里简要介绍其核心思想:

  • 基于直方图的并行学习: LightGBM 的并行学习是基于直方图的。在特征并行中,不同的 worker 在本地构建特征直方图,然后进行全局直方图合并,得到全局最佳分裂点。在数据并行中,每个 worker 使用部分数据构建本地直方图,然后进行局部直方图合并,得到全局直方图。

  • 优化网络通信: LightGBM 使用了高效的网络通信机制 (例如,Reduce Scatter, All Gather 等 MPI 原语) 来加速直方图合并过程,并减少网络通信开销。

并行学习的参数:

  • n_jobs: 控制 LightGBM 使用的 CPU 核心数,用于特征并行。

  • num_machines: 用于数据并行,指定机器数量。

  • local_listen_port: 用于数据并行,指定本地监听端口。

  • machine_rank: 用于数据并行,指定机器 rank。

2.4 代码实践与内容详解

接下来,我们通过 Python 代码示例来演示 LightGBM 的核心原理,并结合代码进行更深入的讲解。

示例:使用 LightGBM 进行二分类任务

import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.datasets import load_breast_cancer from sklearn.metrics import accuracy_score # 1. 加载数据集 data = load_breast_cancer() X, y = data.data, data.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 2. 设置 LightGBM 参数 params = { 'boosting_type': 'gbdt', # GBDT 算法 (默认) 'objective': 'binary', # 二分类任务 'metric': 'binary_logloss', # 评估指标:对数损失 'num_leaves': 31, # 叶节点数量,控制模型复杂度 'learning_rate': 0.05, # 学习率 'feature_fraction': 0.9, # 特征采样比例 (EFB 相关) 'bagging_fraction': 0.8, # 数据采样比例 (GOSS 相关) 'bagging_freq': 5, # bagging 频率 'verbose': 0 # 控制训练过程信息输出 } # 3. 创建 LightGBM 数据集 lgb_train = lgb.Dataset(X_train, y_train) lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train) # 4. 训练模型 gbm = lgb.train(params, lgb_train, num_boost_round=20, # 迭代次数 valid_sets=lgb_eval, # 验证集 early_stopping_rounds=5) # 早停轮数 # 5. 预测 y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration) y_pred_binary = [1 if pred > 0.5 else 0 for pred in y_pred] # 6. 评估模型 accuracy = accuracy_score(y_test, y_pred_binary) print(f'Accuracy: {accuracy:.4f}')

代码详解:

  • 导入库: 导入 lightgbm, sklearn 相关库。

  • 加载数据集: 使用 sklearn.datasets.load_breast_cancer 加载乳腺癌数据集,这是一个经典的二分类数据集。

  • 设置 LightGBM 参数: params 字典中设置了 LightGBM 的各种参数,其中:

    • boosting_type: 'gbdt' 指定使用 GBDT 算法,LightGBM 默认使用 GBDT,也支持 dart, goss, rf 等其他 boosting 类型。

    • objective: 'binary' 指定任务为二分类。

    • metric: 'binary_logloss' 指定评估指标为二分类对数损失。

    • num_leaves: 31 设置叶节点数量,控制树模型的复杂度。Leaf-wise 树生长策略中,num_leavesmax_depth 更重要,因为它直接限制了叶节点的数量。

    • learning_rate: 0.05 设置学习率,控制每次迭代模型更新的步长。

    • feature_fraction: 0.9 特征采样比例,与 EFB 相关。当设置为小于 1 的值时,LightGBM 会在每次迭代中随机选择部分特征进行训练,可以加速训练并防止过拟合。

    • bagging_fraction: 0.8 数据采样比例,与 GOSS 相关。当设置为小于 1 的值时,LightGBM 会使用 GOSS 采样策略进行数据采样。

    • bagging_freq: 5 bagging 频率,每隔 bagging_freq 次迭代进行一次 bagging (数据采样)。

    • verbose: 0 控制训练过程信息输出,设置为 0 则不输出信息。

  • 创建 LightGBM 数据集: 使用 lgb.Dataset 创建 LightGBM 的数据集格式,用于训练和验证。

  • 训练模型: 使用 lgb.train 函数训练模型,参数包括:

    • params: 模型参数。

    • lgb_train: 训练数据集。

    • num_boost_round: 迭代次数 (弱学习器数量)。

    • valid_sets: 验证数据集,用于早停和监控模型性能。

    • early_stopping_rounds: 早停轮数,当验证集指标在 early_stopping_rounds 轮迭代后没有提升时,提前停止训练,防止过拟合。

  • 预测: 使用 gbm.predict 函数进行预测,num_iteration=gbm.best_iteration 指定使用最佳迭代次数的模型进行预测 (早停得到的最佳模型)。

  • 评估模型: 使用 sklearn.metrics.accuracy_score 计算模型在测试集上的准确率。

参数调优与核心原理关联:

  • GOSS 相关参数: bagging_fraction, top_rate, other_rate 可以控制 GOSS 的采样策略。例如,增大 bagging_fraction 可以减少采样比例,加速训练,但可能牺牲精度。

  • EFB 相关参数: feature_fraction, max_conflict_rate 可以控制 EFB 的特征捆绑策略。例如,减小 feature_fraction 可以减少特征数量,加速训练,但可能影响模型性能。sparse_threshold 参数 (未在示例中展示) 可以控制稀疏特征的阈值,影响 EFB 的效果。

  • 直方图算法相关参数: max_bin, min_data_in_bin, bin_construct_sample_cnt 可以控制直方图算法的行为。例如,减小 max_bin 可以加速训练,但可能降低精度。

  • Leaf-wise 生长策略相关参数: num_leaves, max_depth, min_data_in_leaf 可以控制 Leaf-wise 树模型的复杂度,防止过拟合。num_leaves 是控制模型复杂度的关键参数,通常需要仔细调优。

实践建议:

  • 理解参数含义: 深入理解 LightGBM 各个参数的含义和作用,特别是与核心原理相关的参数。

  • 根据数据特点选择参数: 根据数据的特点 (例如,数据量大小、特征维度、稀疏性等) 选择合适的参数。例如,对于大规模数据,可以尝试使用 GOSS 和 EFB 加速训练;对于高维度稀疏数据,EFB 可能非常有效。

  • 交叉验证与网格搜索: 使用交叉验证 (例如,K-折交叉验证) 和网格搜索 (GridSearchCV) 等方法进行参数调优,找到最佳的参数组合。

  • 监控训练过程: 使用验证集监控训练过程,观察模型在验证集上的性能变化,及时调整参数或提前停止训练。

2.5 总结与展望

本章深入探讨了 LightGBM 的核心原理,包括梯度单边采样 (GOSS)、互斥特征捆绑 (EFB)、直方图算法和叶子生长 (Leaf-wise) 策略。这些创新性的技术使得 LightGBM 在训练速度、内存效率和精度方面都取得了显著的提升,使其成为现代机器学习领域中备受欢迎的 GBDT 框架。

LightGBM 的核心价值:

  • 高效性: GOSS, EFB, 直方图算法等技术显著提升了训练速度和内存效率,使其能够高效处理大规模数据和高维度特征。

  • 准确性: Leaf-wise 树生长策略和参数调优使得 LightGBM 能够构建高精度的模型。

  • 易用性: LightGBM 提供了友好的 Python 和 C++ 接口,易于使用和集成。

  • 可扩展性: LightGBM 支持并行学习和 GPU 加速,可以进一步提升训练效率。

未来展望:

LightGBM 作为一个活跃的开源项目,仍在不断发展和完善。未来的发展方向可能包括:

  • 更高效的算法优化: 进一步优化 GOSS, EFB, 直方图算法等核心技术,提升算法效率和精度。

  • 更强大的并行和分布式学习能力: 支持更大规模的数据并行和模型并行,适应超大规模数据集和复杂模型的训练需求。

  • 与其他机器学习框架的集成: 更好地与其他机器学习框架 (例如,TensorFlow, PyTorch) 集成,方便用户在不同的框架之间切换和组合使用。

  • AutoML 和模型解释性: 探索 LightGBM 在 AutoML (自动化机器学习) 和模型解释性方面的应用,使其更加智能化和可解释。

LightGBM 的成功证明了算法创新在提升机器学习性能方面的巨大潜力。随着数据规模和应用场景的不断扩展,LightGBM 将继续在机器学习领域发挥重要作用。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U