参考网址
juejin.cn/post/707757…
总结
这一点和xgboost很像,因为lightgbm和sklearn是2个独立的机器学习算法库,
所以,lightgbm有自己的原生接口建模函数。
同时,为了方便广大的sklearn用户的使用,
LightGBM提供了sklearn风格的API接口,这使得用户可以直接在sklearn的工作流程中使用LightGBM模型,从而方便地进行数据预处理、模型训练和评估。
LightGBM是微软开发的boosting集成学习思想的一种算法,
和XGBoost算法一样,都是对GBDT的优化和高效实现,
原理有一些相似之处,但它很多方面比XGBoost算法有着更为优秀的表现,轻量级,速度快,占用内存小。
LightGBM被命名为“Light”主要是因为它的训练速度非常快,同时内存消耗较低,能够处理大量数据。
具体来说:
1. 训练速度快:相比其他梯度提升框架(如XGBoost),LightGBM在保持训练精度的前提下,能够显著提高训练速度,有时甚至能提高20倍。这主要得益于其独特的算法设计,如逐叶生长的决策树策略等leaf-wise
2. 内存消耗低:LightGBM采用了直方图算法等一系列优化措施,使得其在处理大量数据时,内存消耗相对较低。这使得LightGBM在处理大规模数据集时具有更高的效率和可扩展性。
综上所述,LightGBM被命名为“Light”是为了强调其轻量级、快速和高效的特点。
这些特点使得LightGBM在机器学习任务中,尤其是在处理大规模数据集时,成为一种非常受欢迎的选择。
lightgbm的安装
lightgbm作为常见的强大Python机器学习工具库,安装也比较简单。
lightgbm不在sklearn库中,它是一个单独的库包,和xgboost一样,都是一个单独的库包。
所以,你需要单独安装。
安装起来是非常简单方便的。
大家也可以选择国内的pip源,以获得更好的安装速度:
pip install lightgbm -i https:
level-wise 和 leaf-wise
Level-wise是【按层进行生长】的决策树生长策略。
它遍历一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度(深度不大),不容易过拟合。
然而,level-wise实际上是一种·低效·的算法,因为它不加区分的对待同一层中的所有的叶子,
导致了对很多分裂增益较低的叶子进行了不必要的搜索和分裂,从而带来了额外的开销。
相比之下,Leaf-wise则是一种更为·高效·的策略。它每次从当前的所有叶子节点中,
找到分裂增益最大的一个叶子,然后分裂,如此循环。
因此,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。
但是,Leaf-wise的缺点是可能会长出比较深的决策树,产生过拟合。
为了克服这个问题,一些算法(如LightGBM)在Leaf-wise之上增加了一个最大深度的限制,以在保证高效率的同时防止过拟合。
总的来说,Level-wise和Leaf-wise各有优缺点,具体使用哪种策略取决于具体的应用场景和需求。
XGBoost采用的是Level-wise的生长策略
这种策略能够同时分裂同一层的叶子,从而进行多线程优化,并且不容易过拟合。
然而,这种策略的一个潜在缺点是它不加区分地对待同一层的叶子,
这可能会导致对一些分裂增益较低的叶子进行不必要的搜索和分裂,从而带来额外的计算开销。
LightGBM采用的是Leaf-wise的生长策略
与Level-wise不同,Leaf-wise每次从当前所有叶子中找出分裂增益最大的一个叶子进行分裂,如此循环。
这种策略能更快地找到最优的分裂点,并且可以充分利用信息增益来提高模型的预测能力,从而提高精度。
然而,Leaf-wise的一个潜在缺点是可能会长出比较深的决策树,造成过拟合。
为了克服这个问题,LightGBM在Leaf-wise之上增加了一个最大深度限制,以防止过拟合。
gbdt是二叉树吗
是的,GBDT(Gradient Boosting Decision Tree)是基于二叉树的
它是一种集成模型,基评估器采用CART(分类回归二叉决策树),
并通过Gradient Boosting的方式进行集成。
CART树在构建时,会进行特征选择并根据gini系数和最小平方误差来确定最优切分特征和切分点,从而构建出一棵二叉树。因此,GBDT的基模型(弱分类器)为CART决策树,无论是针对分类问题还是回归问题,都是基于二叉树的。
GBDT、XGBoost和LightGBM之间的关系可以从它们的发展历程和特性来理解
1. GBDT(Gradient Boosting Decision Tree)是机器学习算法中的一种,
它采用Gradient Boosting的方法进行集成学习。
GBDT的基分类器采用CART决策树,并通过串行的方式训练多个基分类器,每个基分类器都会在前一个基分类器的基础上进行优化,从而提升整体的预测精度。
2. XGBoost(eXtreme Gradient Boosting)是GBDT的一个高效实现,
由华盛顿大学的陈天奇博士开发。
XGBoost在GBDT的基础上进行了许多改进,如引入了正则化项、支持并行计算、对缺失值处理等,
从而极大地提升了模型训练速度和预测精度。
可以说,XGBoost是GBDT的一个升级版。
3. LightGBM(Light Gradient Boosting Machine)是微软开发的一个实现GBDT算法的框架,
它支持高效率的并行训练,具有更快的训练速度、更低的内存消耗和更好的准确率等优点。
与XGBoost相比,LightGBM在算法上进行了一些优化,如采用基于直方图的决策树算法、带深度限制的Leaf-wise的叶子生长策略等,
从而进一步提升了模型的性能。
综上所述,GBDT、XGBoost和LightGBM都是基于Gradient Boosting方法的集成学习算法,
它们之间的关系是:
GBDT是基础的机器学习算法,
XGBoost是GBDT的高效实现和升级版,
而LightGBM则是在XGBoost的基础上进行进一步优化和改进的版本。
L1和L2是机器学习和深度学习中常用的两种损失函数,分别称为L1损失函数和L2损失函数。
L1损失函数,平均绝对误差(MAE),mean absolute error
它表示的是预测值与目标值之间的绝对差异的总和。
这种损失函数对于异常值具有较强的鲁棒性(包容性),因为它在计算误差时不会考虑误差的平方,所以不会过度放大异常值的影响。
L2损失函数,也被称为最小二乘误差(LSE)或均方误差(MSE)。
它表示的是预测值与目标值之间所有平方差的总和。
与L1损失函数相比,L2损失函数对于异常值更为敏感,因为它在计算误差时会考虑误差的平方,这可能会放大异常值的影响。
在实际应用中,L2损失函数由于其良好的数学性质(例如连续性和可导性)和计算效率,通常被优先考虑。
然而,当数据集中存在异常值时,L1损失函数可能会是一个更好的选择,因为它对异常值的敏感性较低。
我们训练模型,就是要最小化损失函数。
损失函数越小,说明预测值和真实值之间的差异就越小。
损失函数和目标函数的区别
在算法模型中,损失函数和目标函数是两个相关但不同的概念。
损失函数(Loss Function)主要用于衡量模型预测结果与真实值之间的差异。
它通常是一个关于模型参数的函数,通过调整模型参数使损失函数最小化,达到优化模型的目的。
损失函数的具体形式可以根据不同的问题和模型来选择,以最大程度地反映模型的性能。常见的损失函数有均方误差、交叉熵等。
目标函数(Objective Function)是一个更加宽泛的概念,它通常是优化问题中的一个概念,用于定义最终需要优化的任务目标。
目标函数可以是损失函数本身,也可以是在损失函数基础上加上其他正则项或约束条件的复合函数(综合函数)。
目标函数考虑了模型算法的准确性、模型的复杂度、可解释度等因素,是机器学习任务的真正目标。
通过最小化或最大化目标函数,可以训练出性能更好的机器学习模型。
因此,损失函数是目标函数的一种具体形式,目标函数包含了损失函数并可能考虑其他因素。
在机器学习中,理解目标函数和损失函数的区别是非常重要的,通过合理选择目标函数和损失函数,可以使机器学习模型在实际问题中取得更好的性能。
通过原生接口训练模型
LightGBM内置了建模方式,有如下的数据格式与核心训练方法:
- 基于`lightgbm.Dataset`格式的数据。
- 基于`lightgbm.train`接口训练。
必须满足输入的数据结构的类型,
你想用人家内置的方法,你就必须按照人家的要求来,人家要你输入什么样结构的数据,你就必须输入相应的数据结构的数据。
不然,你就别用。
import json
import lightgbm as lgb
import pandas as pd
from sklearn.metrics import mean_squared_error
print('加载数据...')
df_train = pd.read_csv('./data/regression.train.txt', header=None, sep='\t')
df_test = pd.read_csv('./data/regression.test.txt', header=None, sep='\t')
y_train = df_train[0].values
y_test = df_test[0].values
X_train = df_train.drop(0, axis=1).values
X_test = df_test.drop(0, axis=1).values
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)
params = {
'task': 'train',
'boosting_type': 'gbdt',
'objective': 'regression',
'metric': {'l2', 'auc'},
'num_leaves': 31,
'learning_rate': 0.05,
'feature_fraction': 0.9,
'bagging_fraction': 0.8,
'bagging_freq': 5,
'verbose': 0
}
gbm = lgb.train(params,
lgb_train,
num_boost_round=20,
valid_sets=lgb_eval,
early_stopping_rounds=5)
gbm.save_model('model.txt')
print('开始预测...')
y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)
print('预估结果的rmse为:')
print(mean_squared_error(y_test, y_pred) ** 0.5)
print('完成10轮训练...')
print('第7个特征为:')
print(repr(lgb_train.feature_name[6]))
gbm.save_model('./model/lgb_model.txt')
print('特征名称:')
print(gbm.feature_name())
print('特征重要度:')
print(list(gbm.feature_importance()))
print('加载模型用于预测')
bst = lgb.Booster(model_file='./model/lgb_model.txt')
y_pred = bst.predict(X_test)
print('在测试集上的rmse为:')
print(mean_squared_error(y_test, y_pred) ** 0.5)


设置样本权重
LightGBM的建模非常灵活,它可以支持我们对于每个样本设置不同的权重学习.
设置的方式也非常简单,我们需要提供给模型一组权重数组数据,长度和样本数一致。
如下是一个典型的例子,其中`binary.train`和`binary.test`读取后加载为`lightgbm.Dataset`格式的输入,而在`lightgbm.Dataset`的构建参数中可以设置样本权重(这个例子中是numpy array的形态)。再基于`lightgbm.train`接口使用内置建模方式训练。
如何设置参数
1/控制树的生长

<1>num_leaves
叶子节点的数目。它是控制树模型复杂度的主要参数。
如果是`level-wise`,则该参数为2depth2^{depth}2depth,其中depth为树的深度。
但是当叶子节点数量相同的时候,leaf-wise树要远远深过level-wise树,非常容易导致过拟合。
因此应该让num_leaves小于2depth2^{depth}2depth。
在leaf-wise树中,并不存在depth的概念。因为不存在一个从leaves到depth的合理映射。
<2>min_data_in_leaf
每个叶子节点的最少样本数量。
它是处理`leaf-wise`树的过拟合的重要参数。
将它设为较大的值,可以避免生成一个过深的树。但是也可能导致欠拟合。
<3>max_depth
树的最大深度。该参数可以显式的限制树的深度。
(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`。
- 使用`min_data_in_leaf`和`min_sum_hessian_in_leaf`。
- 通过设置`bagging_fraction`和`bagging_freq`来使用`bagging`。
- 通过设置`feature_fraction`来使用特征子抽样。
- 使用更大的训练数据。
- 使用`lambda_l1`、`lambda_l2`和`min_gain_to_split`来使用正则。
- 尝试`max_depth`来避免生成过深的树。
总的来说,为了控制过度拟合,就是控制树的复杂程度。
比如深度,每个叶子节点中样本的最少数量, 叶子节点的数量。