算法进阶:Lightgbm

1 xgboost存在的问题以及可以改进的地方

在决策树的生成过程中采用了精确贪心的思路,寻找最佳分裂点的时候,使用了预排序算法, 对所有特征都按照特征的数值进行预排序, 然后遍历所有特征上的所有分裂点位,计算按照这些候选分裂点位分裂后的全部样本的目标函数增益,找到最大的那个增益对应的特征和候选分裂点位,从而进行分裂。这样一层一层的完成建树过程, xgboost训练的时候,是通过加法的方式进行训练,也就是每一次通过聚焦残差训练一棵树出来, 最后的预测结果是所有树的加和表示。

因此gboost寻找最优分裂点的复杂度=特征数量×分裂点的数量×样本的数量,因此如果我们相对xgboost做一些优化的话,我们可以从上面的三个角度下手,比如减少特征数量、分裂点的数量或样本的数量等。

2 lightgbm的改进

2.1 减少分裂点数量:直方图算法

直方图算法说白了就是把连续的浮点特征离散化为k个整数(也就是分桶bins的思想),并根据特征所在的bin对其进行梯度累加和个数统计。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。
在这里插入图片描述
这样在遍历到该特征的时候,只需要根据直方图的离散值,遍历寻找最优的分割点即可,由于bins的数量是远小于样本不同取值的数量的,所以分桶之后要遍历的分裂点的个数会少了很多,这样就可以减少计算量。
离散化分桶的好处有:
1、减少了存储空间。xgboost需要32位int存储排序后的索引和32位float存储样本的特征取值。而lightgbm不仅不需要存储排序的结果,并且只需要8位int存储feature bins就行
2、时间复杂度降低:从之前的O(featurevalue_nums-1 features_num )降低到O(bin_nums-1features_num )
3、速度进一步加快:直方图作差加速,当节点分裂成两个时,右边的子节点的直方图其实等于其父节点的直方图减去左边子节点的直方图
4、可以防止过拟合:采用Histogram算法会起到正则化的效果,bin数量决定了正则化的程度,bin越少惩罚越严重,欠拟合风险越高

2.2 减少采样:单边梯度抽样算法(GOSS)

排除梯度小的样本,侧重梯度大的样本(在gbdt中,当损失函数为平凡损失函数时,梯度就是残差)。但是要是盲目的直接去掉这些梯度小的数据,这样就会改变数据的分布。
GOSS 算法保留了梯度大的样本,并对梯度小的样本进行随机抽样,为了不改变样本的数据分布,在计算增益时为梯度小的样本引入一个常数进行平衡。首先将要进行分裂的特征的所有取值按照绝对值大小降序排序(xgboost也进行了排序,但是LightGBM不用保存排序后的结果),然后拿到前a %的梯度大的样本,和剩下样本的b %,在计算增益时,后面的这b% 通过乘上(1-a)/b来放大梯度小的样本的权重。一方面算法将更多的注意力放在训练不足的样本上,另一方面通过乘上权重来防止采样对原始数据分布造成太大的影响。
在这里插入图片描述
在这里插入图片描述

2.3减少特征:互斥特征捆绑算法

在这里插入图片描述

  • 怎么判定哪些特征应该绑在一起?
  • 特征绑在一起之后,特征值应该如何确定呢

对于问题一,捆绑特征就是在干这样的一件事:

  • 首先将所有的特征看成图的各个顶点,将不相互独立的特征(某个特征的所有非0样本和另一个样本所有非0样本都不相同)用一条边连起来,边的权重就是两个相连接的特征的总冲突值(也就是这两个特征上同时不为0的样本个数)。
  • 然后按照节点的度对特征降序排序, 度越大,说明与其他特征的冲突越大
  • 对于每一个特征, 遍历已有的特征簇,如果发现该特征加入到特征簇中的矛盾数不超过某一个阈值,则将该特征加入到该簇中。 如果该特征不能加入任何一个已有的特征簇,则新建一个簇,将该特征加入到新建的簇中。
    在这里插入图片描述
    对于问题二,关键在于绑定几个特征在同一个bundle里需要保证绑定前的原始特征的值可以在bundle里面进行识别。比如,我们把特征A和B绑定到了同一个bundle里面, A特征的原始取值区间[0,10), B特征原始取值区间[0,20), 这样如果直接绑定,那么会发现我从bundle里面取出一个值5, 就分不出这个5到底是来自特征A还是特征B了。 所以我们可以再B特征的取值上加一个常量10转换为[10, 30),这样绑定好的特征取值就是[0,30), 我如果再从bundle里面取出5, 就一下子知道这个是来自特征A的。
    在这里插入图片描述
    在这里插入图片描述
    A这边10个非0,对应了B的10个0, B的5个非0,对应了A的5个0, 而剩下的就是B和A的0对应0, 这时候A还有85个0, B还有85个0, 此时只需要去掉B那边的非0值的下标,合并之后,就能直接区分开0值来自A了

2.4 leaf-wise和level-wise决策树生成算法

lightgbm除了在寻找最优分裂点过程中进行了优化,其实在树的生成过程中也进行了优化, 它抛弃了xgboost里面的按层生长(level-wise), 而是使用了带有深度限制的按叶子生长(leaf-wise)
————————————————
XGBoost 在树的生成过程中采用 Level-wise 的增长策略,该策略遍历一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise是一种低效的算法,因为它不加区分的对待同一层的叶子,实际上很多叶子的分裂增益较低,没必要进行搜索和分裂,因此带来了很多没必要的计算开销(一层一层的走,不管它效果到底好不好)
————————————————
Leaf-wise 则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同 Level-wise 相比,在分裂次数相同的情况下,Leaf-wise 可以降低更多的误差,得到更好的精度。Leaf-wise 的缺点是可能会长出比较深的决策树,产生过拟合。因此 LightGBM 在 Leaf-wise 之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。 (最大信息增益的优先, 我才不管层不层呢)
————————————————

3 lightgbm实战

3.1 基本使用

sklearn接口调用

# 创建模型,训练模型
gbm = LGBMRegressor(objective='regression'
                    ,num_leaves=31
                    ,learning_rate=0.05
                    ,n_estimators=20)
gbm.fit(x_train,y_train
        ,eval_set=[(x_test,y_test)]
        ,eval_metric='l1'
        ,early_stopping_rounds=5)
gbm.score(x_test,y_test)

3.2 调参

1、针对leaf-wise树的参数优化:
	· max_depth: 控制了树的最大深度
	· num_leaves:控制了叶节点的数
	· min_data_in_leaf: 每个叶节点的最少样本数量
2、针对更快的训练速度
	· bagging_fraction 和 bagging_freq 参数来使用bagging方法
	· feature_fraction 参数来使用特征的子抽样
	· max_bin
	· save_binary 在未来的学习过程对数据加载进行加速
3、获得更好的准确率
	· 使用较大的 max_bin (学习速度可能变慢)
	· 使用较小的 learning_rate 和较大的 num_iterations
	· 使用较大的 num_leaves (可能导致过拟合)
	· 使用更大的训练数据
	· 尝试DART
4、缓解过拟合
	· 使用较小的 max_bin,分桶粗一些
	· 使用较小的 num_leaves 不要在单棵树分的太细
	· 使用 lambda_l1, lambda_l2 和 min_gain_to_split 来使用正则
	· 尝试 max_depth 来避免生成过深的树
	· 使用 min_data_in_leaf 和 min_sum_hessian_in_leaf,确保叶子节点有足够多的数据

4 LightGBM的工程优化

4.1 类别特征的支持

4.2 高效并行

4.3 Cache命中率优化


5 参考资料

https://zhongqiang.blog.youkuaiyun.com/article/details/105350579

<think>好的,我现在需要帮助用户找到关于LightGBM算法的代码实现。用户已经提供了三个引用,我需要仔细看看这些引用里有没有相关的代码示例。 首先看引用1,里面提到“使用Python对其进行实现和应用”,但摘要里没有具体代码,可能在文章的后续部分,但用户提供的引用内容里没有显示。不过引用2提到了粒子群优化LightGBM分类算法的Python实现代码,可能包含相关代码。引用3的标题是“原理与代码实战案例讲解”,很可能有具体的代码示例。 用户需要的是LightGBM的基本示例代码,可能包括数据加载、模型训练和预测等步骤。我需要综合这些引用中的信息,特别是引用3,因为它明确提到了代码实战案例。 接下来,我需要确保代码符合用户的要求,并且正确使用LightGBM的API。通常,使用LightGBM的步骤包括安装库、准备数据、创建数据集、设置参数、训练模型和进行预测。此外,可能还需要演示如何与优化算法结合,比如引用2中的粒子群优化,但用户可能更关注基础实现。 检查引用3的内容,假设它详细讲解了代码,那么我可以从中提取关键步骤。例如,加载数据、转换为Dataset格式、定义参数、训练模型和评估。同时,引用2中的示例可能展示了如何用PSO优化LightGBM的超参数,这也是一个有用的扩展,但可能作为进阶内容。 需要确保代码语法正确,使用正确的中文注释,并且结构清晰。另外,用户提到要生成相关问题,我需要根据提供的引用内容,提出与LightGBM实现、优化和应用相关的问题。 最后,按照用户的格式要求,将代码用三个反引号包裹,注明python,并正确添加引用标识。确保回答部分符合用户可见层的指导原则,结构清晰,步骤明确。</think>以下为LightGBM分类算法的Python实现示例代码,包含基础实现和优化算法结合版本: ### LightGBM基础实现代码 ```python import lightgbm as lgb from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score # 加载数据集 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) # 创建LightGBM数据集格式 train_data = lgb.Dataset(X_train, label=y_train) test_data = lgb.Dataset(X_test, label=y_test, reference=train_data) # 设置参数 params = { 'objective': 'binary', 'metric': 'binary_logloss', 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9 } # 模型训练 gbm = lgb.train(params, train_data, valid_sets=test_data, num_boost_round=100) # 预测测试集 y_pred = gbm.predict(X_test) y_pred_binary = [1 if x > 0.5 else 0 for x in y_pred] # 计算准确率 print("准确率:", accuracy_score(y_test, y_pred_binary)) ``` (核心参数说明见引用[3]中关于GBDT参数设置的章节)[^3] ### 粒子群优化LightGBM实现 ```python # 粒子群优化代码框架(需配合上述基础代码使用) from pyswarm import pso def objective_function(params): num_leaves, learning_rate = params model = lgb.LGBMClassifier( num_leaves=int(num_leaves), learning_rate=learning_rate, n_estimators=100 ) model.fit(X_train, y_train) return -model.score(X_test, y_test) # 最小化负准确率 # 参数范围 lb = [10, 0.01] # 下限 ub = [50, 0.3] # 上限 # 运行PSO优化 best_params, best_score = pso(objective_function, lb, ub) print("最优参数:", best_params) ``` (优化算法实现参考引用[2]中粒子群优化框架)[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值