3.1 核心参数 (Core Parameters)


文档摘要

3.1 核心参数 (Core Parameters) 第三章:LightGBM 参数详解 - 3.1 核心参数 (Core Parameters) LightGBM (Light Gradient Boosting Machine) 是一款由微软开发的梯度提升框架,以其高效性、低内存占用和高准确率在机器学习领域广受欢迎。要充分发挥 LightGBM 的性能,理解并合理配置其参数至关重要。本章我们将深入探讨 LightGBM 的核心参数,这些参数直接影响模型的学习过程、训练效率和最终预测效果。 3.1 核心参数 (Core Parameters) 详解 核心参数是 LightGBM 模型的基础,它们定义了学习任务的类型、提升方法、模型复杂度和训练效率等关键要素。

3.1 核心参数 (Core Parameters)

第三章:LightGBM 参数详解 - 3.1 核心参数 (Core Parameters)

LightGBM (Light Gradient Boosting Machine) 是一款由微软开发的梯度提升框架,以其高效性、低内存占用和高准确率在机器学习领域广受欢迎。要充分发挥 LightGBM 的性能,理解并合理配置其参数至关重要。本章我们将深入探讨 LightGBM 的核心参数,这些参数直接影响模型的学习过程、训练效率和最终预测效果。

3.1 核心参数 (Core Parameters) 详解

核心参数是 LightGBM 模型的基础,它们定义了学习任务的类型、提升方法、模型复杂度和训练效率等关键要素。掌握这些参数是构建高效 LightGBM 模型的首要步骤。

以下是 LightGBM 的核心参数,我们将逐一进行详细解释,并结合代码实践加深理解:

  1. objective: 目标函数,定义学习任务的类型以及优化的目标。

  2. boosting_type: 提升类型,决定了使用的提升算法。

  3. num_iterations (或 n_estimators): 迭代次数,也即基学习器(通常是决策树)的数量。

  4. learning_rate (或 eta): 学习率,控制每次迭代更新的步长。

  5. num_leaves: 叶子节点数,控制树模型的复杂度。

  6. tree_learner: 树学习器,指定并行学习的方式。

  7. num_threads (或 n_jobs): 线程数,用于并行计算。

  8. device: 设备类型,选择使用 CPU 或 GPU 进行训练。

  9. seed: 随机种子,用于控制随机性,保证实验的可重复性。

接下来,我们将逐个深入解析这些核心参数,并提供相应的代码示例。

3.1.1 objective:目标函数

参数类型: 字符串或自定义函数

默认值: 'regression'

参数详解:

objective 参数定义了学习任务的类型以及模型需要优化的目标函数。选择合适的目标函数至关重要,因为它直接决定了模型解决问题的方向。LightGBM 提供了丰富的内置目标函数,涵盖了回归、二分类、多分类、排序等多种任务。

常见 objective 取值及其含义:

  • 回归 (Regression):

    • 'regression_l2' (或 'l2', 'mean_squared_error', 'mse', 'l2_root', 'root_mean_squared_error', 'rmse'): L2 损失,均方误差,适用于回归任务。

    • 'regression_l1' (或 'l1', 'mean_absolute_error', 'mae'): L1 损失,平均绝对误差,对异常值更鲁棒。

    • 'huber': Huber 损失,结合了 L1 和 L2 损失的优点,对异常值不敏感,且在误差较小时具有 L2 损失的优点。

    • 'fair': Fair 损失,另一种对异常值鲁棒的回归损失函数。

    • 'poisson': Poisson 回归,适用于目标变量为泊松分布的计数型数据。

    • 'quantile': Quantile 回归,用于预测分位数,例如预测中位数、90% 分位数等。

  • 二分类 (Binary Classification):

    • 'binary': 二元交叉熵损失函数,用于二分类任务,输出概率值。
  • 多分类 (Multiclass Classification):

    • 'multiclass': 多类别交叉熵损失函数,用于多分类任务,需要指定 num_class 参数。

    • 'multiclassova' (或 'ova', 'one_vs_all'): One-vs-All 多分类,将多分类问题转化为多个二分类问题。

  • 排序 (Ranking):

    • 'lambdarank': LambdaRank 损失,用于排序任务,优化 NDCG 等排序指标。
  • 其他:

    • 'tweedie': Tweedie 回归,适用于目标变量为 Tweedie 分布的数据,可以处理不同方差和均值关系的数据。

    • 'gamma': Gamma 回归,适用于目标变量为 Gamma 分布的正值数据。

    • 'negative_binomial': 负二项回归,适用于目标变量为负二项分布的计数型数据,可以处理过离散的数据。

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_regression, make_classification from sklearn.model_selection import train_test_split # 1. 回归任务 (Regression) X_reg, y_reg = make_regression(n_samples=1000, n_features=10, random_state=42) X_train_reg, X_test_reg, y_train_reg, y_test_reg = train_test_split(X_reg, y_reg, test_size=0.2, random_state=42) lgb_reg = lgb.LGBMRegressor(objective='regression_l2', random_state=42) # 使用 L2 损失 lgb_reg.fit(X_train_reg, y_train_reg) y_pred_reg = lgb_reg.predict(X_test_reg) print("Regression Task - Objective: regression_l2") # 2. 二分类任务 (Binary Classification) X_clf, y_clf = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42) X_train_clf, X_test_clf, y_train_clf, y_test_clf = train_test_split(X_clf, y_clf, test_size=0.2, random_state=42) lgb_clf = lgb.LGBMClassifier(objective='binary', random_state=42) # 使用 binary 目标函数 lgb_clf.fit(X_train_clf, y_train_clf) y_pred_clf = lgb_clf.predict(X_test_clf) print("\nBinary Classification Task - Objective: binary") # 3. 多分类任务 (Multiclass Classification) X_multi, y_multi = make_classification(n_samples=1000, n_features=10, n_classes=3, n_informative=5, n_redundant=5, random_state=42) X_train_multi, X_test_multi, y_train_multi, y_test_multi = train_test_split(X_multi, y_multi, test_size=0.2, random_state=42) lgb_multi = lgb.LGBMClassifier(objective='multiclass', num_class=3, random_state=42) # 使用 multiclass 目标函数,并指定 num_class lgb_multi.fit(X_train_multi, y_train_multi) y_pred_multi = lgb_multi.predict(X_test_multi) print("\nMulticlass Classification Task - Objective: multiclass")

内容详解:

在上述代码示例中,我们分别演示了回归、二分类和多分类任务中 objective 参数的使用。

  • 对于回归任务,我们选择了 'regression_l2' 作为目标函数,这意味着模型将最小化预测值与真实值之间的均方误差。

  • 对于二分类任务,我们选择了 'binary',模型将使用二元交叉熵损失函数,输出样本属于正类的概率。

  • 对于多分类任务,我们选择了 'multiclass',并设置了 num_class=3 来指定类别数量。模型将使用多类别交叉熵损失函数,输出样本属于每个类别的概率。

选择 objective 的建议:

  • 根据任务类型选择: 首先明确你的任务是回归、分类还是排序。

  • 考虑数据特性: 如果数据存在较多异常值,可以考虑使用 'regression_l1', 'huber', 'fair' 等对异常值鲁棒的损失函数。对于计数型数据,可以选择 'poisson''negative_binomial'

  • 评估指标: objective 的选择应与你最终评估模型的指标相匹配。例如,如果你的评估指标是 RMSE,那么 'regression_l2' 通常是一个不错的选择。

  • 实验和调优: 在实际应用中,建议尝试不同的 objective 值,并通过交叉验证等方法选择最优的参数。

3.1.2 boosting_type:提升类型

参数类型: 字符串

默认值: 'gbdt'

参数详解:

boosting_type 参数决定了 LightGBM 使用的提升算法。不同的提升算法在训练速度、准确率和鲁棒性方面有所差异。LightGBM 提供了以下几种主要的提升类型:

  • 'gbdt' (Gradient Boosting Decision Tree): 梯度提升决策树,经典的梯度提升算法,也是 LightGBM 的默认 boosting 类型。它通过迭代地训练决策树来拟合残差,具有较高的准确率和较好的泛化能力。

  • 'rf' (Random Forest): 随机森林,一种 bagging 算法,通过 Bagging 的方式构建多个决策树,并进行投票或平均预测结果。相比 GBDT,RF 的训练速度更快,且更不容易过拟合,但通常准确率会稍逊于 GBDT。在 LightGBM 中实现的 RF 与传统的 RF 有一些区别,它仍然是 boosting 的框架。

  • 'dart' (Dropouts meet Multiple Additive Regression Trees): DART 算法,一种具有 dropout 功能的 GBDT。在每次迭代中,DART 会随机 dropout 一部分树,这可以有效地缓解过拟合,并提高模型的泛化能力。DART 的训练速度通常比 GBDT 慢。

  • 'goss' (Gradient-based One-Side Sampling): 基于梯度的单边采样,GOSS 是一种高效的梯度提升算法。与传统的 GBDT 不同,GOSS 不是使用所有样本来计算梯度,而是通过对梯度进行采样来估计梯度。GOSS 主要关注梯度大的样本(即对损失函数影响较大的样本),并对梯度小的样本进行随机采样。这可以在保证准确率的同时,显著减少计算量,加快训练速度。尤其适用于数据量大、特征维度高的数据集。

Mermaid 图表:

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 1. GBDT lgb_gbdt = lgb.LGBMClassifier(boosting_type='gbdt', random_state=42) lgb_gbdt.fit(X_train, y_train) print("Boosting Type: GBDT") # 2. Random Forest lgb_rf = lgb.LGBMClassifier(boosting_type='rf', random_state=42) lgb_rf.fit(X_train, y_train) print("\nBoosting Type: RF") # 3. DART lgb_dart = lgb.LGBMClassifier(boosting_type='dart', random_state=42) lgb_dart.fit(X_train, y_train) print("\nBoosting Type: DART") # 4. GOSS lgb_goss = lgb.LGBMClassifier(boosting_type='goss', random_state=42) lgb_goss.fit(X_train, y_train) print("\nBoosting Type: GOSS")

内容详解:

代码示例展示了如何通过 boosting_type 参数选择不同的提升算法。我们可以根据实际情况选择合适的 boosting 类型。

选择 boosting_type 的建议:

  • 默认 'gbdt': 通常情况下,'gbdt' 是一个稳妥的选择,它在大多数数据集上都能取得不错的性能。

  • 大数据集和高维度: 如果数据集非常大或者特征维度很高,可以尝试 'goss',它能显著加速训练过程。

  • 缓解过拟合: 如果模型容易过拟合,可以尝试 'dart''rf',它们具有更好的泛化能力。

  • 追求速度: 如果对训练速度有较高要求,可以考虑 'rf',但需要注意可能牺牲一定的准确率。

  • 实验对比: 建议在实际项目中,尝试不同的 boosting_type,并通过交叉验证等方法选择最优的参数。

3.1.3 num_iterations (或 n_estimators):迭代次数

参数类型: 整数

默认值: 100

参数详解:

num_iterations (或 n_estimators) 参数指定了 boosting 过程中的迭代次数,也就是模型中基学习器(通常是决策树)的数量。迭代次数越多,模型越复杂,理论上可以更好地拟合训练数据,但也更容易过拟合。

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 不同迭代次数 iterations_list = [50, 100, 200, 500] for n_iterations in iterations_list: lgb_model = lgb.LGBMClassifier(n_estimators=n_iterations, random_state=42) # 使用 n_estimators lgb_model.fit(X_train, y_train) print(f"Number of Iterations: {n_iterations}")

内容详解:

代码示例中,我们尝试了不同的迭代次数 (num_iterationsn_estimators)。迭代次数增加,模型训练时间通常会增加,模型在训练集上的表现也会提升,但在测试集上的表现则不一定。

选择 num_iterations 的建议:

  • 迭代次数并非越多越好: 过多的迭代次数会导致过拟合,降低模型在未知数据上的泛化能力。

  • 结合 learning_rate: num_iterationslearning_rate 通常需要联合调整。较小的 learning_rate 通常需要更多的迭代次数才能达到较好的效果。

  • 使用早停法 (Early Stopping): 在实际应用中,通常会结合早停法来确定最佳的迭代次数。早停法会在验证集上的指标不再提升时提前停止训练,避免过拟合。LightGBM 提供了 early_stopping_rounds 参数来实现早停。

3.1.4 learning_rate (或 eta):学习率

参数类型: 浮点数

默认值: 0.1

参数详解:

learning_rate (或 eta) 参数控制了每次迭代更新的步长,也称为收缩率 (shrinkage rate)。学习率决定了每棵树对最终预测结果的影响程度。较小的学习率意味着每次迭代的步长较小,模型学习得更慢,但可能更稳定,也更不容易过拟合。较大的学习率则相反。

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 不同学习率 learning_rates = [0.01, 0.05, 0.1, 0.3] for lr in learning_rates: lgb_model = lgb.LGBMClassifier(learning_rate=lr, random_state=42) # 使用 learning_rate lgb_model.fit(X_train, y_train) print(f"Learning Rate: {lr}")

内容详解:

代码示例展示了不同学习率对模型训练的影响。较小的学习率通常需要更多的迭代次数才能收敛,但可能获得更稳定的结果。

选择 learning_rate 的建议:

  • 小学习率 vs 大学习率: 小学习率通常泛化能力更好,但训练速度慢;大学习率训练速度快,但容易过拟合。

  • num_iterations 联合调整: learning_ratenum_iterations 通常需要联合调整。一般来说,减小 learning_rate 的同时,可以适当增加 num_iterations

  • 常见的学习率范围: 常用的学习率范围为 0.01 到 0.2。可以先尝试默认值 0.1,然后根据实际情况进行调整。

  • 学习率衰减 (Learning Rate Decay): LightGBM 也支持学习率衰减,可以在训练过程中逐渐减小学习率,以提高模型的性能和稳定性。可以通过 learning_rate_decay_powermin_learning_rate 等参数进行设置。

3.1.5 num_leaves:叶子节点数

参数类型: 整数

默认值: 31

参数详解:

num_leaves 参数控制了每棵树的最大叶子节点数,是控制树模型复杂度的主要参数。num_leaves 越大,树模型越复杂,可以学习到更精细的特征,但也更容易过拟合。

关系: num_leaves 近似于 2^max_depth,但 num_leaves 对模型复杂度的控制更加直接。理论上,num_leaves = 2^max_depth 时,两者复杂度相当,但实际上 LightGBM 使用 leaf-wise (最佳优先) 的树生长策略,相比 depth-wise (按层生长) 的策略,在相同的 num_leaves 下,leaf-wise 的树通常更深,模型复杂度更高,但也能在一定程度上提高准确率。

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_features=10, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 不同叶子节点数 num_leaves_list = [15, 31, 63, 127] for num_leaves_val in num_leaves_list: lgb_model = lgb.LGBMClassifier(num_leaves=num_leaves_val, random_state=42) # 使用 num_leaves lgb_model.fit(X_train, y_train) print(f"Number of Leaves: {num_leaves_val}")

内容详解:

代码示例展示了不同 num_leaves 值对模型复杂度的影响。num_leaves 越大,模型复杂度越高,训练时间可能增加,也更容易过拟合。

选择 num_leaves 的建议:

  • 控制模型复杂度: num_leaves 是控制模型复杂度的关键参数,需要根据数据集大小和特征数量进行调整。

  • 防止过拟合: 如果模型容易过拟合,可以减小 num_leaves 的值。

  • 数据集大小: 对于小数据集,num_leaves 不宜设置过大,一般在 31 或更小;对于大数据集,可以适当增大 num_leaves,例如 63、127 甚至更大。

  • max_depth 配合: 虽然 num_leaves 更直接,但也可以结合 max_depth 参数来限制树的深度,进一步控制模型复杂度。

3.1.6 tree_learner:树学习器

参数类型: 字符串

默认值: 'serial'

参数详解:

tree_learner 参数指定了树学习器类型,决定了 LightGBM 如何进行并行学习。LightGBM 提供了以下几种树学习器:

  • 'serial': 单机串行树学习器,也是默认值。在单台机器上串行构建每棵树。

  • 'feature': 特征并行树学习器。在特征维度上进行数据并行,每个 worker 负责一部分特征子集,寻找局部最佳切分点,然后进行汇总。特征并行适用于特征数量巨大,但数据量相对较小的情况。

  • 'data': 数据并行树学习器。在数据维度上进行数据并行,每个 worker 负责一部分数据子集,在本地构建直方图,然后进行汇总。数据并行适用于数据量巨大,但特征数量相对较小的情况。

  • 'voting': 投票并行树学习器。 Voting Parallel 是 Data Parallel 的改进版本,旨在进一步减少数据通信开销,提高数据并行效率。

Mermaid 图表:

代码实践 (Python):

树学习器类型的选择通常在分布式训练环境下更有意义。在单机环境下,默认的 'serial' 已经足够高效。以下代码示例主要展示如何设置 tree_learner 参数,实际性能提升需要在分布式环境中体现。

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split X, y = make_classification(n_samples=1000, n_features=100, random_state=42) # 增加特征维度 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 不同树学习器 (单机演示,分布式环境效果更明显) tree_learners = ['serial', 'feature', 'data', 'voting'] for learner_type in tree_learners: lgb_model = lgb.LGBMClassifier(tree_learner=learner_type, random_state=42) # 使用 tree_learner lgb_model.fit(X_train, y_train) print(f"Tree Learner: {learner_type}")

内容详解:

代码示例展示了如何设置不同的 tree_learner 类型。在单机环境下,不同 tree_learner 类型的性能差异可能不明显。

选择 tree_learner 的建议:

  • 单机环境: 默认 'serial' 即可。

  • 分布式环境:

    • 特征维度高: 优先考虑 'feature' 特征并行。

    • 数据量大: 优先考虑 'data''voting' 数据并行。'voting' 通常是更高效的数据并行方式。

  • 网络环境: 在网络带宽受限的环境下,'voting' 可以减少通信开销,提高效率。

  • 实验对比: 在分布式环境中,建议根据实际情况尝试不同的 tree_learner,并进行性能测试。

3.1.7 num_threads (或 n_jobs):线程数

参数类型: 整数

默认值: -1 (表示使用所有 CPU 核心)

参数详解:

num_threads (或 n_jobs) 参数控制了 LightGBM 在并行计算时使用的线程数。合理设置线程数可以充分利用多核 CPU 的计算能力,加快训练速度。

代码实践 (Python):

import lightgbm as lgb from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split import time X, y = make_classification(n_samples=10000, n_features=20, random_state=42) # 增加数据量 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 不同线程数 threads_list = [1, 2, 4, -1] # -1 代表使用所有核心 for n_threads in threads_list: start_time = time.time() lgb_model = lgb.LGBMClassifier(n_jobs=n_threads, random_state=42) # 使用 n_jobs lgb_model.fit(X_train, y_train) end_time = time.time() print(f"Number of Threads: {n_threads}, Training Time: {end_time - start_time:.4f} seconds")

内容详解:

代码示例展示了不同线程数对训练时间的影响。通常情况下,增加线程数可以缩短训练时间,但并非线性加速。当线程数超过 CPU 核心数时,可能会因为线程切换的开销而导致性能下降。

选择 num_threads 的建议:

  • 默认值 -1: 通常情况下,使用默认值 -1,让 LightGBM 自动使用所有可用的 CPU 核心是一个不错的选择。

  • 根据 CPU 核心数: 可以根据机器的 CPU 核心数来设置 num_threads。例如,如果机器有 8 核 CPU,可以尝试设置 num_threads=8

  • 避免过度并行: 线程数不宜设置过大,超过 CPU 核心数可能会导致性能下降。

  • 资源限制: 在资源受限的环境下,可以适当减小 num_threads,例如在共享服务器上训练模型时。

3.1.8 device:设备类型

参数类型: 字符串

默认值: 'cpu'

参数详解:

device 参数指定了 LightGBM 使用的设备类型,可以选择使用 CPU 或 GPU 进行训练。使用 GPU 可以利用 GPU 的并行计算能力,显著加速训练过程,尤其是在处理大规模数据集时。

可选值:

  • 'cpu': 使用 CPU 进行训练 (默认)。

  • 'gpu': 使用 GPU 进行训练。使用 GPU 需要安装 GPU 版本的 LightGBM,并确保系统已安装 CUDA 和相应的 GPU 驱动。


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