LightGBM原理和调参

背景知识

LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,具有支持高效率的并行训练、更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以处理海量数据等优点。

普通的GBDT算法不支持用mini-batch的方式训练,在每一次迭代的时候,都需要多次遍历整个训练数据。这样如果把整个训练数据装进内存则会限制训练集的大小,如果不装进内存,反复的读写数据又会大量消耗时间,特别不适合工业级海量数据的应用。LGBM的提出就是为了解决这些问题。

XGBoost

在LGBM提出之前,应用最广泛的GBDT工具就是XGBoost了,它是基于预排序的决策树算法。这种构建决策树的算法基本思想是:

  • 首先,对所有特征都按特征的数值进行预排序;
  • 其次,在遍历分割点的时候用O(#data)的代价找到一个特征上的最佳分割点;
  • 最后,在找到一个特征的最佳分割点后,将数据分裂成左右子节点。

这样预排序算法的优点是能精确地找到分割点,但是缺点也很明显:

  1. 空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如,为了后续快速的计算分割点,保存了排序后的索引),这就需要消耗训练数据两倍的内存。
  2. 时间开销大。在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。
  3. cache优化不友好。在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层生成树的时候 ,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。

LGBM的优化

为了弥补XGBoost的缺陷,并且能够在不损害准确率的条件下加快GBDT模型的训练速度,LGBM在传统的GBDT算法上进行了如下优化:

  1. 基于Histogram的决策树算法。
  2. 单边梯度采样(Gradient-based One-side Sampling, GOSS):使用GOSS可以减少大量只具有小梯度的数据实例,这样在计算信息增益的时候只利用剩下的具有高梯度的数据就可以了,相比XGBoost遍历所有特征节省了不少时间和空间上的开销。
  3. 互斥特征捆绑(Exclusive Feature Bundling, EFB):使用EFB可以将许多互斥的特征绑定为一个特征,这样达到了降维的目的。
  4. 带深度限制的Leaf-wise的叶子生长策略:大多数GBDT工具使用低效的按层生长(level-wise)的决策树生长策略,因为它不加区分的对待同一层叶子,带来了很多没必要的开销,实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。LGBM使用了带有深度限制的按叶子生长(leaf-wise)算法。
  5. 直接支持类别特征(Categorical Feature)。
  6. 支持高效并行。
  7. Cache命中率优化。

LGBM基本原理

LGBM是基于Histogram的决策树算法。直方图算法的基本思想是:先将连续的浮点特征值离散成K个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

在这里插入图片描述

直方图算法的简单理解为:首先确定对于每个特征需要多少个箱子(bin)并为每

### LightGBM中的特征重要性计算方法 在LightGBM中,存在两种主要的方式用于评估特征的重要性:`split` `gain`。 - **Split 方式** 当采用`importance_type='split'`时,特征的重要程度由该特征被选作分裂节点的次数决定。一个特征如果频繁地作为最佳分裂点,则表明它对于模型构建具有较高的价值[^1]。 - **Gain 方式** 另一种衡量标准是基于增益(`importance_type='gain'`),即每次分裂所带来的纯度增加量之总。具体来说,就是指某个属性能够带来多少信息熵减少或者不纯度降低的程度。这种方式更能体现单次分裂对整体性能改进的作用大小。 这两种不同的定义反映了各自侧重点的不同——前者强调的是频率上的优势;后者则更关注于质量方面的影响力度。使用者可以根据具体的业务需求选择合适的评价指标来进行解释或调参工作。 ```python # Python代码示例:获取特征重要性 import lightgbm as lgb model = lgb.LGBMClassifier() model.fit(X_train, y_train) # 输出按'split'方式排序后的特征名称及其对应的得分 for idx, score in enumerate(model.booster_.feature_importance(importance_type="split")): print(f"Feature {idx}: Split Importance Score={score}") # 同样也可以查看'gain' for idx, score in enumerate(model.booster_.feature_importance(importance_type="gain")): print(f"Feature {idx}: Gain Importance Score={score}") ``` #### 类别特征处理与特征重要性 值得注意的是,在许多其他机器学习库中,类别型变量通常需要转换成独热编码形式才能参与建模过程,这不仅增加了内存占用还可能导致维度灾难问题的发生。然而,LightGBM特别针对这一痛点进行了优化设计,允许直接传入未经变换过的分类数据,并且能够在内部高效地完成相应的运算逻辑[^3]。这种特性使得即使面对含有大量离散取值字段的数据集时也能保持良好的可扩展性预测准确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值