一文速学-LightGBM模型算法原理以及实现+Python项目实战

LighGBM

前言

LighGBM作为GBDT算法的衍生模型,在其他论文研究以及数学建模比赛中十分常见。如果不熟悉GBDT算法的可以去看看我的上一篇文章,过多关于GBDT的细节不再过多描述。主要将讲述一下LighGBM较于GBDT算法的改进以及独特算法细节优化,以及比XGBoost和CatBoost算法较好的应用场景。总体而言,LightGBM在性能和效率方面都有很大的优势,特别适用于中小规模的数据集和高维度的特征。

一、LighGBM算法概述

LightGBM(Light Gradient Boosting Machine)是一种基于梯度提升决策树(Gradient Boosting Decision Tree,简称GBDT)算法的机器学习框架。GBDT是一种集成学习方法,它通过逐步训练一系列决策树来提升模型性能。每个新的决策树会尝试纠正前面树的预测误差。LightGBM是一种基于GBDT的算法,但它在构建决策树和训练过程中采用了一些优化策略,以提高效率和性能。下表为GBDT衍生模型优化对比:

算法差异点GBDTXGBoostLightGBMCatBoost
弱学习器CART回归树1.CART回归树2.线性学习器3.Dart树Leaf-wise树对称树
寻找分裂点贪心算法近似算法直方图算法预排序算法
稀疏值处理稀疏感知算法EFB(互斥特征捆绑)
类别特征不直接支持,可自行编码后输入模型同GBDT直接支持,GS编码直接支持,Ordered TS编码
并行支持不可以可以可以可以

一图流展示优化点:
在这里插入图片描述

既然LightGMB算法模型建立的比XGBoost晚,那么其算法必然在XGBoost模型上进行进一步优化。首先XGBoost空间消耗大,因为XGBoost构建决策树的算法基本思想是预排序算法,这样的算法需要保存数据的特征值,还保存了特征排序的结果,这就需要消耗训练数据两倍的内存。其次,时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。

因此LightGMB主要着重解决的是构建决策树以及算法开销上的优化。

二、算法改进之处

1.Leaf-wise生长策略

LightGBM采用了leaf-wise的生长策略,与大多数GBDT传统的level-wise策略相比,能够更快地找到更优的分割点。这是因为leaf-wise策略每次选择能够降低损失函数最多的叶子节点进行分裂,从而更快地构建深度树。
在这里插入图片描述

在这里插入图片描述

1.1选择最佳分割点

在每次构建分割节点时,Leaf-wise策略会选择能够最大程度降低损失函数的特征和分割点。这是通过遍历特征的所有可能分割点,并计算分割后的两个子节点上的损失函数来实现的。

1.2贪心选择

Leaf-wise策略是一种贪心算法,每次选择能够最大程度减小损失函数的特征和分割点。这种选择策略使得树能够更快地学习到数据的细节和特征之间的关系。

1.3剪枝

在构建完一个节点后,Leaf-wise策略还会进行剪枝操作,即比较当前节点的损失减小值与一个阈值。如果损失减小值不满足阈值条件,就停止节点的继续分割,从而避免过拟合。

1.4叶子节点分配

Leaf-wise策略中,新的样本会被分配到现有的叶子节点中。如果某个叶子节点的分割后损失函数下降不足,该节点会停止继续分割,成为一个叶子节点。

1.5深度

由于Leaf-wise策略的贪心特性,它能够构建更深的树。然而,由于每次只选择一个分割点,有时候会导致某些叶子节点包含较少样本,可能会引发过拟合问题。因此,在训练时需要通过参数来控制树的最大深度或者其他正则化手段。

2.直方图特征优化

LightGBM中的直方图优化是一种针对特征处理的技术,用于加速决策树的构建过程。它通过将连续的特征值划分为一系列离散的直方块(即直方图),从而减少了计算复杂度和内存占用。

在这里插入图片描述

2.1特征值划分

对于每个连续特征,LightGBM首先会将特征的取值范围按照一定的间隔(bin)划分成离散的区间,形成一个直方图。每个区间被称为一个bin,其中包含了该特征值在这个区间内的样本。这种离散化分桶思路其实有很多优点的, 首先最明显就是内存消耗的降低,xgboost需要用32位的浮点数去存储特征值, 并用32位的整型去存储索引,而Lightgbm的直方图算法不仅不需要额外存储预排序的结果,而且可以只保存特征离散化后的值,而这个值一般用8位整型存储就足够了,内存消耗可以降低为原来的1/8。

在这里插入图片描述

以下图片来自https://blog.csdn.net/wuzhongqiang/article/details/105350579 推荐阅读。

在这里插入图片描述

2.2统计梯度和Hessian

每个bin中,LightGBM会计算样本的梯度和Hessian的累积值。这些值用于在寻找最佳分割点时评估损失函数的变化。

在这里插入图片描述

2.3选择分割点

在寻找最佳分割点时,LightGBM会遍历每个bin之间的边界,以及每个bin内部的候选分割点。它使用累积的梯度和Hessian值来评估在这些分割点上的损失减小情况,从而选择最优的分割点。直方图优化还能够直接处理类别特征和缺失值。对于类别特征,LightGBM会将不同类别分配到不同的bin中。对于缺失值,LightGBM会将缺失值分配到一个特殊的bin中,从而有效地处理缺失信息。

3.单边梯度抽样算法(GOSS)

一般来说我们会在数据预处理部分就会开始做数据均衡工程,但是LightGBM内置GOSS算法的主要目标是加速训练过程,同时保持模型性能。它通过保留梯度较大的样本来减少数据集的大小,以便在每次迭代中更有效地更新模型。而数据均衡算法主要关注处理样本不平衡问题,通过调整样本权重或采样策略来平衡不同类别的影响。

GBDT中每个数据都会有不同的梯度值,即梯度小的样本,训练误差也比较小,梯度比较小的样本对于降低残差的作用效果不是太大,所以我们可以关注梯度高的样本

算法流程如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CgfE7kN0-1692751421156)(C:\Users\10799\AppData\Roaming\Typora\typora-user-images\image-20230822114728503.png)]

通过GOSS算法,LightGBM能够在保持模型性能的同时,降低训练数据集的大小,从而加速训练过程。这对于大规模数据集尤其有用,可以减少每次迭代所需的计算和存储资源。需要注意的是,GOSS算法可能会引入一些噪声,因为它会丢弃一部分样本,但通常情况下,这种噪声的影响可以通过调整超参数来控制。
在这里插入图片描述

4.互斥特征捆绑算法(EFB)

“互斥特征捆绑算法”(Exclusive Feature Bundling,EFB)是LightGBM中用于处理高维度数据中特征相关性问题的一种技术。其思想是将高度相关的特征捆绑在一起,将它们视为一个整体进行处理,以降低模型的复杂性和过拟合风险。

4.1特征相关性捆绑

在高维度数据中,有时会存在许多高度相关的特征。这些特征可能会导致模型过拟合,因为它们提供了类似的信息,但会增加模型的复杂性。EFB的思想是将这些高度相关的特征捆绑在一起,视为一个特征组。

极端稀疏数据如下图就可以比较直观的看到效果,当然实际算法和PCA降维算法类似。

在这里插入图片描述

4.2特征组代表

在每个特征组中,EFB会选择一个特征作为代表性特征。这个代表性特征在特征组内与其他特征的相关性较低,因此它可以被视为特征组的代表。
在这里插入图片描述

EFB 算法利用特征和特征间的关系构造一个加权无向图,并将其转换为图着色的问题来求解,求解过程中采用的贪心策略。

  • 首先将所有的特征看成图的各个顶点,将不相互独立的特征用一条边连起来,边的权重就是两个相连接的特征的总冲突值(也就是这两个特征上同时不为0的样本个数)。
  • 然后按照节点的度对特征降序排序, 度越大,说明与其他特征的冲突越大
  • 对于每一个特征, 遍历已有的特征簇,如果发现该特征加入到特征簇中的矛盾数不超过某一个阈值,则将该特征加入到该簇中。 如果该特征不能加入任何一个已有的特征簇,则新建一个簇,将该特征加入到新建的簇中。

在这里插入图片描述

4.3特征转换

在训练过程中,EFB会将特征组内的特征进行转换,使其与代表性特征之间的相关性最小化。这有助于减少特征捆绑对模型性能的影响。通过将高度相关的特征捆绑在一起,EFB减少了模型中的特征数量,从而降低了模型的复杂性。这有助于减少过拟合风险,提高模型的泛化能力。

讲了太多理论内容怕大家一时半会消化不过来,直接上实例展示一下lightgbm算法的强大。

三、基于LightGBM用户购买意愿预测模型搭建

经过了上面的学习我们清楚LightGBM模型的几个要点,不需要再对数据进行数据均衡处理,也不需要额外的缺失值处理,并且还不需要特征降维操作,能够直接处理类别特征,直接免去了大量的数据工程。

那么我们首先预览一下数据集:
在这里插入图片描述

这是2021 华数杯全国大学生数学建模竞赛C题数据集,列表每一个维度特征对应着客户个人特征调查表中收集的维度数据。

在这里插入图片描述

以及

  • a1、舒适性(环保与空间座椅)整体表现满意度得分
  • a2、经济性(耗能与保值率)整体 满意度得分
  • a3、安全性表现(刹车和行车视野)整体满意度得分
  • a4、动力性表现(爬 坡和加速)整体满意度得分
  • a5、驾驶操控性表现(转弯和高速的稳定性)整体满意度得 分
  • a6、外观内饰整体表现满意度得分
  • a7、配置与质量品质整体满意度得分

如果根据a1到a7正常来推算购买意愿是比较容易的算法,但是结合用户特征表B表的数据,我们还需要根据问题不同来处理每一个对应维度的数据是否定类还是定量。那么这些问题如果采用传统的机器学习来说就会比较麻烦,需要数据清洗和数据均衡,因为有购买意愿的用户是极少的:

在这里插入图片描述

且数据也存在大量空值需要处理:

在这里插入图片描述

但是我们使用LightGBM就可以无视以上这些情况直接训练,以下是一些常用的LightGBM训练参数:

  1. boosting_type(提升类型): 可选值包括’gbdt’(传统的梯度提升树)、‘rf’(随机森林)、‘dart’(Dropouts meet Multiple Additive Regression Trees)和’goss’(Gradient-based One-Side Sampling)等。
  2. num_leaves(叶子节点数): 定义每棵树的叶子节点数量,较大的值可以增加模型的复杂性,但也可能导致过拟合。
  3. learning_rate(学习率): 控制每次迭代中模型参数的更新步长。较小的值会使训练过程更加稳定,但可能需要更多的迭代次数。
  4. n_estimators(迭代次数): 指定训练的树的数量,通常需要根据问题的复杂程度来设置。
  5. max_depth(树的最大深度): 限制每棵树的最大深度,可以用于防止过拟合。
  6. min_child_samples(叶子节点最小样本数): 指定每个叶子节点上的最小样本数,用于控制剪枝,防止生成过深的树。
  7. subsample(子采样比例): 控制每棵树训练时的样本子采样比例,用于防止过拟合。
  8. colsample_bytree(特征子采样比例): 控制每棵树训练时的特征子采样比例,用于防止特征间的强相关性影响。
  9. reg_alpha(L1正则化项)reg_lambda(L2正则化项): 用于控制模型复杂性,防止过拟合。
  10. scale_pos_weight(正负样本权重平衡): 用于处理类别不平衡问题,增加少数类别的样本权重。
  11. objective(目标函数): 定义要最小化的损失函数,例如’regression’(回归问题)或’binary’(二分类问题)等。
  12. metric(评估指标): 用于评估模型性能的指标,如’rmse’(均方根误差)、‘auc’(ROC曲线下面积)等。

这只是一些常用的LightGBM训练参数示例,实际使用中还有很多其他参数可以进行调节。不同的问题和数据集可能需要不同的参数配置,因此在使用LightGBM时,您可以根据问题的特点进行参数调优,以获得最佳的模型性能。可以通过查阅LightGBM的官方文档和相关资源,深入了解每个参数的含义和使用方法。

import lightgbm as lgb
from sklearn.model_selection import train_test_split
import joblib
from sklearn.metrics import mean_squared_errorX_train, X_test, y_train, y_test = train_test_split(X, target, test_size=0.2)# 创建成lgb特征的数据集格式
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)# 定义训练参数
params = {'boosting_type': 'gbdt','objective': 'binary',  # 适用于二分类问题'metric': 'binary_logloss',  # 适用于二分类问题的损失函数'num_leaves': 31,'learning_rate': 0.05,'feature_fraction': 0.9,'bagging_fraction': 0.8,'bagging_freq': 5,'verbose': 0
}# 训练模型
num_round = 100  # 迭代次数
bst = lgb.train(params, lgb_train, num_round, valid_sets=[lgb_eval], early_stopping_rounds=10)# 保存模型
model_filename = 'lgb_model.pkl'
joblib.dump(bst, model_filename)# 预测数据集
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)# 评估模型
print('The rmse of prediction is:', mean_squared_error(y_test,y_pred))

在这里插入图片描述

混淆矩阵:

from sklearn.metrics import confusion_matrix
import numpy as np
# 使用 NumPy 将小于 0.5 的值归为 0,大于等于 0.5 的值归为 1
y_pred_binary = (y_pred >= 0.5).astype(int)labels=[0,1]
cm= confusion_matrix(y_test, y_pred_binary,labels=[0,1])
sns.heatmap(cm,annot=True ,fmt="d",xticklabels=labels,yticklabels=labels)plt.title('confusion matrix')  # 标题
plt.xlabel('Predict lable')  # x轴
plt.ylabel('True lable')  # y轴
plt.show()

在这里插入图片描述

样本案例的数据不太好,太不均衡了没办法,下次如果有好的数据集再重新跑一遍。

总结

最后还是和上篇算法的XGBoost算法对比一下:

LightGBM的优点:

  1. 更快的训练速度: LightGBM采用了GOSS(Gradient-based One-Side Sampling)和直方图优化等技术,使得它在训练速度上通常比XGBoost更快。这对于处理大规模数据集非常有益。
  2. 更低的内存消耗: LightGBM通过对特征值的离散化处理和直方图优化,减少了内存的使用,尤其适合处理大数据。
  3. 更好的处理高维稀疏数据: LightGBM在处理高维稀疏数据时表现更好,这是因为它可以使用直方图优化技术。
  4. 更好的处理类别特征: LightGBM能够直接处理类别特征,无需进行独热编码等处理。
  5. 支持并行化: LightGBM支持并行化计算,可以有效地利用多核处理器。

LightGBM的缺点:

  1. 对异常值敏感: LightGBM的样本采样技术可能对异常值比较敏感,因此在处理异常值时需要小心。

XGBoost的优点:

  1. 较强的正则化: XGBoost在正则化方面更强,可以有效防止过拟合。
  2. 广泛应用: XGBoost已经存在较长时间,在许多数据科学竞赛和实际应用中得到了广泛应用,有更多的实践经验。

XGBoost的缺点:

  1. 较大的内存消耗: XGBoost在内存消耗方面相对较大,对于大规模数据集可能会受到限制。
  2. 速度相对较慢: 相对于LightGBM,XGBoost的训练速度可能稍慢。

总体来说,LightGBM和XGBoost都是非常出色的梯度提升树算法实现,在不同场景下可能有不同的优势。选择哪个算法取决于数据集的大小、特征的性质、计算资源以及具体的问题需求。在实际使用中,通常需要尝试不同的算法并进行参数调优,以找到最适合问题的算法和配置。

泛应用,有更多的实践经验。

XGBoost的缺点:

  1. 较大的内存消耗: XGBoost在内存消耗方面相对较大,对于大规模数据集可能会受到限制。
  2. 速度相对较慢: 相对于LightGBM,XGBoost的训练速度可能稍慢。

总体来说,LightGBM和XGBoost都是非常出色的梯度提升树算法实现,在不同场景下可能有不同的优势。选择哪个算法取决于数据集的大小、特征的性质、计算资源以及具体的问题需求。在实际使用中,通常需要尝试不同的算法并进行参数调优,以找到最适合问题的算法和配置。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/101618.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

批量爬虫采集完成任务

批量爬虫采集是现代数据获取的重要手段,然而如何高效完成这项任务却是让许多程序员头疼的问题。本文将分享一些实际操作价值高的方法,帮助你提高批量爬虫采集的效率和专业度。 目标明确,任务合理划分: 在开始批量爬虫采集前&…

Python爬虫(十四)_BeautifulSoup4 解析器

CSS选择器:BeautifulSoup4 和lxml一样,Beautiful Soup也是一个HTML/XML的解析器,主要的功能也是如何解析和提取HTML/XML数据。 lxml只会局部遍历,而Beautiful Soup是基于HTML DOM的,会载入整个文档,解析整…

详细介绍如何基于ESP32实现气象站数据显示--附源码

功能介绍: 驱动ili9341 从京东获取天气数据 开始使用 拿到钥匙 1.从京东注册账号 2.从网站获取密钥 安装ESP32 SDK ESP-IDF Programming Guide - ESP32 - — ESP-IDF Programming Guide latest documentation 笔记: 该项目兼容 ESP-IDF 3.X 分支和 4…

【Linux驱动】NVIDIA Jetson Orin NX有时开机启动慢(5~10分钟)

1、问题描述 新到手的 Orin NX 有时开机启动慢,多次测试,总结出规律:在连接网线的情况,启动很慢(5~10分钟);不连接网线的情况下是正常启动速度。 2、原因分析 在连接网线的情况下启动,卡在如下界面很长时间: 可见打印信息: Start HTTP Boot over IPv6. Error: Co…

『论文精读』FastViT(ICCV 2023,Apple开源)论文解读

『论文精读』FastViT(ICCV 2023,Apple开源)论文解读 文章目录 一. FastViT简介二. 模型架构2.1. Stage 的内部架构2.2. Stem 的结构2.3. Patch Embedding 的架构2.4. 位置编码 三. 参考文献 论文下载链接:https://arxiv.org/pdf/2303.14189.pdf论文代码…

BLFS学习系列 第25章. 图形环境库 —— libdrm

一、简介 libdrm提供了一个用户空间库,用于在支持ioctl接口的操作系统上访问直接渲染管理器(DRM)。libdrm是一个低级别库,通常由图形驱动(程序)使用,如Mesa DRI驱动(程序&#xff0…

基于java+swing俄罗斯方块

基于javaswing俄罗斯方块 一、系统介绍二、功能展示三、其他系统实现五、获取源码 一、系统介绍 项目类型:Java SE项目(awtswing)非开源 项目名称:俄罗斯方块(Tertis) 主要技术:java、awt、swing等技术 …

【玩转Linux操作】crond的基本操作

🎊专栏【玩转Linux操作】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【Counting Stars 】 欢迎并且感谢大家指出小吉的问题🥰 文章目录 🍔概述🍔命令⭐常用选项 🍔练…

图解算法--排序算法

目录 1.冒泡排序算法 2.选择排序算法 3.插入排序算法 4.希尔排序算法 5.归并排序算法 6.快速排序算法 1.冒泡排序算法 原理讲解: 从待排序的数组中的第一个元素开始,依次比较当前元素和它相邻的下一个元素的大小。如果当前元素大于相邻元素&#x…

剪枝基础与实战(1): 概述

本文介绍基于L1正则化的剪枝原理,并以VGG网络进行实战说明。将从零详细介绍模型训练、稀疏化、剪枝、finetune的全过程,提供详细的源码及说明,有助于对剪枝的熟练掌握,后续也会对yolov8进行剪枝的介绍。 论文: Learning Efficient Convolutional Networks through Network …

SpringBoot项目(支付宝整合)——springboot整合支付宝沙箱支付 从极简实现到IOC改进

目录 引出git代码仓库准备工作支付宝沙箱api内网穿透 [natapp.cn](https://natapp.cn/#download) springboot整合—极简实现版1.导包配置文件2.controller层代码3.进行支付流程4.支付成功回调 依赖注入的改进1.整体结构2.pom.xml文件依赖3.配置文件4.配置类,依赖注入…

渗透测试方法论

文章目录 渗透测试方法论1. 渗透测试种类黑盒测试白盒测试脆弱性评估 2. 安全测试方法论2.1 OWASP TOP 102.3 CWE2.4 CVE 3. 渗透测试流程3.1 通用渗透测试框架3.1.1 范围界定3.1.2 信息搜集3.1.3 目标识别3.1.4 服务枚举3.1.5 漏洞映射3.1.6 社会工程学3.1.7 漏洞利用3.1.8 权…

根据源码,模拟实现 RabbitMQ - 虚拟主机 + Consume设计 (7)

目录 一、虚拟主机 Consume设计 1.1、承接问题 1.2、具体实现 1.2.1、消费者订阅消息实现思路 1.2.2、消费者描述自己执行任务方式实现思路 1.2.3、消息推送给消费者实现思路 1.2.4、消息确认 一、虚拟主机 Consume设计 1.1、承接问题 前面已经实现了虚拟主机大部分功…

【linux】2 Linux编译器-gcc/g++和Linux调试器-gdb

文章目录 一、Linux编译器-gcc/g使用1.1 背景知识1.2 gcc如何完成1.3 函数库1.4 gcc选项 二、linux调试器-gdb使用2.1 背景2.2 开始使用 总结 ヾ(๑╹◡╹)ノ" 人总要为过去的懒惰而付出代价ヾ(๑╹◡╹)ノ" 一、Linux编译器-gcc/g使用 1.1 背景…

JS加密的域名锁定功能,JShaman支持泛域名

JShaman的域名锁定功能,支持泛域名 JShaman的JS代码混淆加密中,有一项“域名锁定”功能。使用此功能后,代码运行时会检测浏览器地址中的域名信息,如是非指定域名,则不运行,以此防止自己网站的JS代码被复制…

python的文件操作

前言 打印内容到屏幕 最简单的输出方式是调用print函数,此函数会将你传递的表达式转化成字符串表达式,并将结果写道标准输出中。 读取键盘输入 python提供了两个raw_input和input内置函数从标准输入中读取一行文本,默认的标准输入是键盘。 …

Android NDK JNI与Java的相互调用

一、Jni调用Java代码 jni可以调用java中的方法和java中的成员变量,因此JNIEnv定义了一系列的方法来帮助我们调用java的方法和成员变量。 以上就是jni调用java类的大部分方法,如果是静态的成员变量和静态方法,可以使用***GetStaticMethodID、CallStaticObjectMethod等***。就…

docker安装fastDFS

一、docker安装 1、搜索镜像 2、拉取镜像 最新版本: docker pull delron/fastdfs3、使用镜像构建容器 3.1 创建tracker容器 docker run -dti --networkhost --name my-tracker -v /opt/zdxf/soft/fastdfs/tracker:/var/fdfs -v /etc/localtime:/etc/localtime d…

Nvidia Jetson 编解码开发(3)解决H265解码报错“PPS id out of range”

1.问题描述 基于之前的开发程序 Nvidia Jetson 编解码开发(2)Jetpack 4.x版本Multimedia API 硬件编码开发--集成encode模块_free-xx的博客-CSDN博客 通过Jetson Xavier NX 硬编码的H265发出后, 上位机断点播放发出来的H265码流, 会报“PPS id out of range” 错误 …

【C语言】喝汽水问题

大家好!今天我们来学习C语言中的喝汽水问题! 目录 1. 题目内容: 2. 思路分析 2.1 方法一 2.2 方法二 2.3 方法三 3. 代码实现 3.1 方法一 3.2 方法二 3.3 方法三 1. 题目内容 喝汽水,1瓶汽水1元,2个空瓶可以…