集成思想

鲁棒性
在AI中,随机抽取特征列的目的在于让算法变得健壮

使用全部的列,未必就是最好的,
最完美的特征是不重不漏,
但现实中提取的特征有着大量的重复,还有遗漏,是即重又漏
另外,还有一些特征实际上是噪声,以为它有用,实际上它是多余的

这时,提取90%的特征,有可能漏选重要特征,也有可能漏选噪声
如果多选一些,就是暴力计算,那么必定有些选择效果好,有些效果差

如此,哪些特征是效果好的,哪些特征效果是差的,就能稍微区分一些了

这个思想极其重要!

最开始的时候,一组特征入模,训练,出结果

现在是基于实际情况,将这一组特征拆分多组特征,每组特征入模,训练,出结果
这样的单个模型 就是一个弱分类器





综合多个弱分类器去评价,而不是使用一组特征一次训练出一个结果

这就是集成思想

三个臭皮匠...







lightgbm原理


LightGBM算法是在2017年由微软公司正式推出并开源的。
这一算法是基于梯度提升决策树(GBDT)的分布式梯度提升框架,
由微软旗下的DMKT(Distributed Machine Learning Toolkit)团队开发,
并由2014年首届阿里巴巴大数据竞赛的获胜者之一柯国霖老师带领进行。

LightGBM以其速度快、效率高、准确性好等特点,在机器学习领域,尤其是各类比赛中,被广泛应用。
它使用基于直方图的算法,将连续特征值分段,减少了计算量,从而提高了训练速度。
同时,LightGBM支持并行学习,可以充分利用多核CPU资源,提高训练效率,
并采用了高效的内存管理机制,降低了内存的使用量。

此外,LightGBM还支持多种优化算法和正则化技术,
如Gradient-based One-Side Sampling (GOSS) 和 Exclusive Feature Bundling (EFB) 等,
这些技术可以有效地防止过拟合,提高模型的准确性。

LightGBM(Light Gradient Boosting Machine)算法原理主要基于梯度提升框架,
是一种用于解决分类、回归和排序等问题的机器学习算法。

该算法由微软团队开发,旨在提供高效、快速和准确的梯度提升算法实现。
以下是对LightGBM算法原理的详细解析:

一、梯度提升框架
LightGBM采用了梯度提升(Gradient Boosting)框架,这是一种集成学习方法,
通过迭代地构建多个弱学习器(通常是决策树)来组合成一个强大的模型。

在每一次迭代中,模型都会根据 前一次迭代的预测结果与实际值之间的差异(即残差)
来构建一个新的弱学习器,
以逐步优化模型的预测能力。

二、基于树的模型
LightGBM使用了基于树的模型作为弱学习器,每棵树由多个节点组成,
每个节点都包含一个特征和一个阈值。

通过比较样本的特征值与阈值的大小,
将样本分配到左子树或右子树,从而实现对样本的分类或回归。


三、高效的特征分裂策略
直方图算法:
LightGBM采用直方图算法来优化决策树的构建过程。
在训练前,算法会对样本中 每一维特征进行排序,并划分成多个直方图(默认划分256个)。
- 相当于将第一维特征划分为256个等级

在后续的训练中,算法仅需要使用直方图作为“特征”进行决策树的构建,
这大大减少了对样本集的遍历次数,提高了训练速度。

个人理解:
将样本数据映射到一个256分段的数据集上,
对于每一维数据,后续就处理这256个数据,不再读取原数据了

Leaf-wise(叶子结点分裂):
与传统的Level-wise(层级分裂)不同,LightGBM采用Leaf-wise分裂策略。
这种策略在每次 分裂时选择对当前样本集 贡献最大的特征和阈值,
从而减少了树的深度,提高了训练速度和模型的预测能力。


四、优化技术
梯度单边采样(GOSS):LightGBM引入了梯度单边采样策略,
即只考虑正向梯度或负向梯度较大的样本进行决策树的构建。
这种策略减少了样本采样的复杂度,提高了训练速度,并且实验证明其效果优于随机采样策略。

互斥特征捆绑(EFB):针对高维稀疏特征,LightGBM采用互斥特征捆绑策略,
将一组互斥的特征绑定在一起进行分桶,
从而减少了特征的数量,降低了模型的复杂度,提高了泛化能力。

直接支持类别特征:LightGBM可以直接处理类别特征,而无需进行独热编码等预处理。这减少了内存消耗,并提高了训练速度。


五、目标函数与正则化
LightGBM的目标函数包括损失函数和正则项,
通过梯度提升算法来优化目标函数,求得最优的模型参数。
正则项用于控制模型的复杂度,防止过拟合。

六、并行计算
LightGBM还支持多线程和并行计算,可以充分利用多核CPU的计算能力,加速模型的训练过程。


综上所述,LightGBM算法通过结合梯度提升框架、
基于树的模型、高效的特征分裂策略、优化技术以及并行计算等技术手段,
实现了高效、快速和准确的机器学习算法。

这些特点使得LightGBM在处理大规模数据集时表现出色,是机器学习领域中的重要工具之一。



将稀疏矩阵中 大概率/经常 同时取0的特征绑定为一个新的特征

互斥特征捆绑(Exclusive Feature Bundling,简称EFB)
是LightGBM(Light Gradient Boosting Machine)框架中的一种重要技术,
旨在通过减少特征数量来提高训练速度和效率。

具体来说,EFB技术通过捆绑互斥的特征来降低特征维度,从而减少寻找最佳切分点的消耗。
以下是对EFB技术的详细解释:

定义与原理

互斥特征捆绑(EFB)是一种特征降维技术,
它基于观察到的高维数据中特征的稀疏性。
在许多实际应用场景中,尤其是处理文本或类别数据时,
通过独热编码(One-Hot Encoding)等方式产生的特征往往是稀疏的,
即许多特征很少同时取非零值。

EFB技术利用这种稀疏性,
将互斥的特征(即很少同时取非零值的特征)捆绑成一个新的特征,
从而达到降维的目的。

实现过程

EFB技术的实现过程大致可以分为以下几个步骤:

构图:
将每个特征视为图中的一个顶点,
对于非互斥的特征(即存在同时取非零值的样本)进行连边,
边的权重设置为特征同时不为零的样本数目。

排序:
根据顶点的度(即与之相连的边的数量,反映了特征与其他特征的冲突程度)对特征进行降序排序。
度越大的特征,表明它与其他特征的冲突越大,
越不可能与其他特征进行捆绑。

捆绑:设置一个最大冲突阈值K,遍历排序后的特征,尝试将每个特征加入到已有的特征捆绑簇中。
如果加入某个特征后,该捆绑簇中的冲突数没有超过K,
则将该特征捆绑入该簇;
否则,新建一个特征捆绑簇,并将该特征加入其中。

特征合并:
在特征捆绑完成后,需要对捆绑后的特征进行合并处理。
由于LightGBM基于直方图算法进行计算,
因此只需要为不同的特征重新分配不重叠的取值空间(即bin值),
并通过引入偏移常量(offset)来解决特征值的分离问题。
优点与应用


EFB技术的优点主要包括:

提高训练速度:
通过减少特征数量,降低了模型训练过程中的计算复杂度,从而提高了训练速度。

降低内存消耗:
特征数量的减少也意味着内存消耗的降低,这对于处理大规模数据集尤为重要。

保持模型性能:
尽管EFB技术减少了特征数量,但由于捆绑的是互斥特征,
因此通常不会对模型的性能产生显著影响。

EFB技术在许多领域都有广泛的应用,特别是在处理高维稀疏数据时表现出色。
例如,在推荐系统中,用户的行为数据往往非常稀疏,且许多行为特征之间互斥,
因此EFB技术可以有效地降低特征维度,提高模型训练效率。

综上所述,互斥特征捆绑(EFB)是LightGBM框架中的一种重要技术,
它通过捆绑互斥特征来降低特征维度,从而提高模型训练速度和效率。

互斥特征捆绑的互斥指什么

这部分仅这人理解/猜测

假设下面是12列数据排成一行的结果
000000001000
000000000100
000000000010
000000000001
000000000000

这12列组合后的结果,反反复复就这5种,
互斥指这5种结果互不相同,

那么就可以将这12列绑定为一个新的特征,其值的范围是
5,4,3,2,1,0
或者0.5,0.4,0.3,0.2,0.1也行
意在按某种方法某5个不同的值就可以了

此部分仅个人理解/猜测,不知道lightgbm是不是这样做的,
也不知道lightgbm说的互斥是不是这个意思







官网https://lightgbm.readthedocs.io/en/latest/


GBDT如何利用残差构建下一棵树

论文阅读《LightGBM: A Highly Efficient Gradient Boosting Decision Tree》

最大增益分裂等原理讲述







分裂节点

在LightGBM(以及许多其他决策树和梯度提升框架)中,
分裂节点是指决策树构建过程中的一个关键步骤,它决定了树的结构和深度。
具体来说,分裂节点涉及以下几个方面:

分裂节点的定义
节点:
在决策树中,每个内部节点代表一个特征上的测试(或条件),
用于将数据集分割成不同的子集。
根节点是整个树的起点,
而叶节点(或终端节点)则不包含进一步的测试,而是直接给出预测结果。

分裂:
分裂节点是指根据某个特征的值将节点中的数据集分割成两个或多个子集的过程。
这个过程通常基于某种准则(如信息增益、基尼不纯度减少量或均方误差减少量)
来选择最佳分裂特征和分裂点。

分裂节点的过程

在LightGBM中,分裂节点的过程大致如下:

选择分裂特征:
对于当前节点,算法会评估所有可用特征,
并计算每个特征作为分裂特征时的增益(即分裂后数据集纯度的提升量)。
增益的计算通常依赖于目标函数
(对于分类问题可能是交叉熵损失,对于回归问题可能是均方误差)
的梯度信息。

确定分裂点:
对于选定的分裂特征,算法会进一步确定最佳分裂点(即在该特征上将数据集分割成两个子集的具体值)。
在LightGBM中,为了提高效率,
它使用直方图算法来近似连续特征的分布,并基于直方图来快速找到最佳分裂点。

分裂数据集:
根据选定的分裂特征和分裂点,将当前节点中的数据集分割成两个子集,并创建相应的子节点。

递归分裂:
对每个子节点重复上述过程,直到满足停止条件
(如达到最大深度max_depth、节点包含的样本数少于某个阈值、增益小于某个阈值等)。

max_depth与分裂节点的关系
max_depth参数设置了决策树的最大深度,
即树中从根节点到最远叶节点的最长路径上的节点数。
它直接限制了树可以分裂的次数,从而影响了树的复杂度和模型的过拟合风险。

当树的深度达到max_depth时,无论当前节点的增益有多大,都不会再进行分裂。
因此,max_depth是控制树生长和防止过拟合的一个重要手段。

综上所述,分裂节点是决策树构建过程中的核心步骤,它决定了树的结构和性能。
而max_depth参数则通过限制树的最大深度来间接影响分裂节点的过程,
从而控制模型的复杂度和过拟合风险。





lightgbm必须在编译时设置使用GPU
https://lightgbm.readthedocs.io/en/stable/GPU-Tutorial.html


设置参数:在训练模型时,通过设置相关参数来指定使用GPU进行计算。
例如,在LightGBM的Python接口中,你可以通过传递device='gpu'参数来指定使用GPU进行计算


lightgbm参数

objective

核心参数

objective

multiclass(多分类)

LightGBM的objective参数用于定义学习任务的目标函数,它可以根据不同的学习任务进行设置。
除了multiclass(多分类)之外,objective参数还有多种其他值,主要包括但不限于以下几类:

1. 回归任务
regression:默认回归任务,使用均方误差作为损失函数。
regression_l1:L1正则化的回归,等同于绝对值误差。
huber:使用Huber损失函数,结合了L1和L2损失的优点,对异常值更加鲁棒。
fair:Fair损失函数,用于回归任务,具有某些特定的统计特性。
poisson:泊松回归,适用于计数数据的回归问题。

2. 二分类任务
binary:二分类任务,使用对数损失函数(logistic loss)。

3. 排序任务
lambdarank:用于排序任务的LambdaRank目标函数。


其他注意事项
自定义损失函数:
除了上述预定义的目标函数外,用户还可以指定自定义的损失函数。
自定义损失函数需要符合特定的签名,
如objective(y_true, y_pred) -> grad, hess,
其中y_true是真实标签,y_pred是预测标签,grad和hess分别是梯度值和二阶导数值。

参数的具体使用:
在实际应用中,应根据数据情况和任务类型选择合适的objective参数值。
例如,在回归任务中,如果数据中存在较多的异常值,
可以考虑使用huber损失函数以提高模型的鲁棒性。

参考官方文档:
由于LightGBM版本更新可能会引入新的目标函数或修改现有目标函数的行为,
因此建议查阅最新的LightGBM官方文档以获取最准确的信息。

综上所述,LightGBM的objective参数具有多种不同的值,用于适应不同类型的机器学习任务。
在实际应用中,应根据具体需求选择合适的值。



metric

Metric Parameters

l1, absolute loss, aliases: mean_absolute_error, mae, regression_l1

l2, square loss, aliases: mean_squared_error, mse, regression_l2, regression

rmse, root square loss, aliases: root_mean_squared_error, l2_root

rmse

Root(根)的作用
保持量纲一致性:均方误差(Mean Squared Error, MSE)是误差平方的平均值,
其单位通常是原始数据单位的平方。

通过取平方根,RMSE的单位恢复到与原始数据相同的量纲,
这使得RMSE在解释上更为直观,可以直接与原始数据的数值进行比较。

放大较小误差:
虽然平方运算放大了所有误差(无论大小),
但取平方根则在一定程度上“缩小”了较大的误差值,
相对于MSE而言,RMSE对较小的误差更为敏感。
这种特性使得RMSE在评估模型性能时,能够更好地反映出模型在整体预测准确性上的细微差别。

便于比较:
由于RMSE保持了与原始数据相同的量纲,
因此它使得不同数据集或不同模型之间的预测准确性比较变得更加直接和方便。
同时,RMSE的值越小,通常表示模型的预测性能越好。

RMSE的应用
RMSE作为一种评估指标,在多个领域都有广泛的应用,包括但不限于:

机器学习:在回归问题中,RMSE是衡量模型预测性能的重要指标之一。通过比较不同模型的RMSE值,可以选择出预测性能最优的模型。
气象学:用于评估数值模型预测大气层行为的准确性。
生物信息学:用于量测重叠蛋白质分子间的距离。
经济学:用于判断一个经济模型是否符合经济指标。

multi_logloss, log loss for multi-class classification,
aliases: multiclass, softmax, multiclassova, multiclass_ova, ova, ovr




数据集相关

reference

reference

lightgbm的Dataset的参数reference官方解释如下:
reference : Dataset or None, optional (default=None) If this is Dataset for validation, training data should be used as reference.

可是为什么验证集要参考或者引用训练集呢,有什么作用?

在使用LightGBM时,验证集(validation set)引用或参考训练集(training set)的原因和作用
主要涉及到LightGBM内部的一些优化和处理机制。
具体来说,这主要与LightGBM如何处理分类特征和缺失值有关。

分类特征处理:
LightGBM在内部使用了一种特殊的算法来处理分类特征,
这种算法需要知道每个分类特征在训练数据中的可能取值。
当验证集引用训练集时,LightGBM可以使用训练集中分类特征的值来正确地处理验证集中的分类特征。

缺失值处理:
LightGBM也有一套处理缺失值的机制。
当验证集引用训练集时,LightGBM可以根据训练集中的信息来更合理地处理验证集中的缺失值。

特征对齐:
通过引用训练集,LightGBM可以确保训练和验证过程中的特征是对齐的,
即两者使用的是相同的特征集和特征顺序。

性能优化:
在某些情况下,引用训练集可以帮助LightGBM在内部进行一些优化,从而提高训练和验证的效率。
总的来说,验证集引用训练集主要是为了确保在训练和验证过程中,
数据的一致性和处理的正确性,
特别是涉及到分类特征和缺失值的处理。
这样做可以提高模型的训练效果和验证的准确性。


数据的一致性和处理的正确性,边界,缺失值,特征对齐...
这些可以归于特征工程,这是训练之前就应该处理好的,
lightgbm内部处理了一些,但还是要自己提前处理好

对于iris数据集,是否添加reference结果都一样,精度都是1.0

# 创建数据集
# label : list, numpy 1-D array, pandas Series / one-column DataFrame
train_data = lgb.Dataset(X_train, label=y_train)

#reference : Dataset or None, optional (default=None) If this is Dataset for validation, training data should be used as reference.
# test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)
test_data = lgb.Dataset(X_test, label=y_test)



特征直方图max_bin:[LightGBM] [Info] Total Bins 86

bin 英/bɪn/ 美/bɪn/ n.箱子;垃圾箱;(有盖)大容器,箱,柜

每个特征 最多 划分为多少个箱子
模型只是参考用户所输入的参数,
具体如何分箱,全体数据集划分多少个箱子,仍以模型的自我决定为主
这个参数通常是先让模型自主决定,出现问题时再人工介入调整

在LightGBM的训练过程中,
日志输出的这句话[LightGBM] [Info] Total Bins 86
表示的是特征直方图(Histogram)的总箱子(Bins)数量为86。

LightGBM是一种基于梯度提升框架的机器学习算法,
特别适用于分类、回归等多种类型的机器学习任务。
它使用了直方图算法来寻找最佳的特征分割点,
这种算法将连续的特征值划分为离散的箱子(Bins),然后根据这些箱子来计算分割点的增益。

这里的“Total Bins 86”指的就是在所有特征上,总共划分出了86个这样的箱子。
这个数量是由LightGBM的参数决定的,
比如max_bin参数就可以用来控制每个特征的最大箱子数。
调整这个参数可以影响模型的性能和训练速度,
因为更多的箱子可以提供更细粒度的特征分割,但也会增加计算成本。

在LightGBM训练过程中,当使用iris数据集时,
日志输出的[LightGBM] [Info] Total Bins 86
表明在所有的特征上总共划分了86个直方图箱子(Bins)。
iris数据集包含四个特征列:花萼长度、花萼宽度、花瓣长度和花瓣宽度。
这86个箱子并不是平均分配到这四个特征上的,而是根据LightGBM的直方图算法自动决定的。

以下是LightGBM如何将iris的四个特征列划分为86个桶的详细解释:

1. 直方图算法概述
LightGBM采用了直方图算法来优化决策树的构建过程。
直方图算法的主要思想是将连续的特征值划分为离散的箱子,
然后在这些箱子上进行决策树的构建。
这样做的好处是减少了原始数据的扫描次数,从而提高了训练速度。

2. 箱子数量的决定因素
max_bin参数:LightGBM允许用户通过max_bin参数来设置每个特征的最大箱子数。
默认情况下,这个值可能是255(具体值可能因版本而异)。
然而,实际的箱子数量可能会少于这个值,具体取决于特征的独特值数量和分布。

特征独特值:
对于每个特征,LightGBM会根据其独特值的数量和分布来划分箱子。
如果某个特征的独特值数量少于max_bin,则只会创建相应数量的箱子。

全局箱子总数:
日志中输出的86个箱子是全局的箱子总数,它是所有特征上箱子数量的总和。
因此,不同特征上可能会有不同数量的箱子。

3. 划分过程
排序与划分:
在训练前,LightGBM会对每个特征的值进行排序,
并根据max_bin参数和特征的独特值分布来划分箱子。
划分的过程可能会采用贪心算法或其他启发式方法来寻找最优的箱子边界。

合并稀疏特征:
对于稀疏特征(尽管iris数据集本身并不稀疏),
LightGBM还支持互斥特征捆绑(EFB)技术,这可以将互斥的特征捆绑在一起进行分桶,
从而进一步减少特征数量和计算复杂度。
然而,在iris数据集的情况下,这一技术可能并不适用。

4. 总结
因此,当LightGBM在iris数据集上训练并输出[LightGBM] [Info] Total Bins 86时,这表示在所有四个特征上总共划分了86个箱子。这些箱子的具体分配取决于每个特征的独特值数量和分布,以及max_bin参数的设置。由于iris数据集的特征数量较少且每个特征的独特值数量也有限,因此实际的箱子数量可能会远少于max_bin参数的默认值。

需要注意的是,由于LightGBM的内部实现细节可能会随着版本的更新而发生变化,因此上述解释基于LightGBM的一般工作原理和特性。在实际应用中,建议参考最新版本的LightGBM官方文档以获取最准确的信息。

根据前面说的直方图算法,分桶是什么意思,这个桶是什么?如果两个数据放一个桶里,是不是就是两个数据合为一个数据的意思 ?

在LightGBM的直方图算法中,“分桶”是一个关键的概念,
它指的是将连续的特征值划分为一系列离散的区间(即“桶”)。
这里的“桶”并不是指物理上的数据存储结构,而是一种逻辑上的划分方式,
用于简化特征值的处理,提高模型的训练效率和性能。

分桶的含义
离散化:
直方图算法通过将连续的特征值划分为离散的桶,
将原始数据从连续空间映射到离散空间。
这有助于减少数据的复杂性,使得模型更容易处理。

简化计算:
在划分桶之后,LightGBM只需在每个桶内计算统计信息(如梯度和、梯度和的平方等),
而无需遍历每个数据点的原始特征值。
这大大简化了计算过程,提高了训练速度。

正则化效果:
从某种程度上讲,分桶还起到了一种正则化的作用。
通过将相似的特征值划分到同一个桶中,
模型对数据的细节特征变得不那么敏感,从而有助于防止过拟合。

桶的具体表现
区间划分:
每个桶代表一个特征值区间,区间内的所有特征值都被视为相等(在决策树分裂的上下文中)。
因此,桶并不是将多个数据点合并为一个数据点,
而是将具有相似特征值的数据点归入同一个类别(即桶)中。

统计信息:
对于每个桶,LightGBM会计算一些统计信息,
如该桶内样本的数量、梯度和等。
这些统计信息将用于后续的决策树构建过程。

两个数据放一个桶里
当两个数据点的特征值位于同一个桶内时,
这并不意味着这两个数据点被合并为一个数据点。
而是说在决策树分裂的上下文中,这两个数据点在特征值上被视为相似或等价,
因此它们将基于相同的桶内统计信息来进行决策树的构建。

总结
在LightGBM的直方图算法中,“分桶”是将连续特征值划分为离散区间的过程,
每个桶代表一个特征值区间,并包含该区间内所有特征值的统计信息。
这种划分方式有助于简化计算、提高训练速度,并起到一定程度的正则化作用。
而两个数据点位于同一个桶内并不意味着它们被合并为一个数据点,
而是说在决策树分裂的上下文中它们被视为相似或等价。



max_depth

max_depth, default = -1, type = int

    limit the max depth for tree model.
    This is used to deal with over-fitting when #data is small.
    Tree still grows leaf-wise
    <= 0 means no limit

- 决策树划分时,从root节点开始,到叶子节点分支上的节点个数,为树的深度(depth),
- 叶子节点存储的是分类结果,不再划分数据,比如min_data_in_leaf参数可以确定一个叶子最多存储多少个数据
- 如果只有一次划分,就是一个root节点,加上两个叶子节点,此时的depth为1,max_depth亦为1
- 有多个分支时,max_depth是所有分支中最大的depth

在数据结构与算法中,二叉树的深度指节点所在的层数,第一层root的深度为1
具体地:
  根节点的深度为1(或者有些定义中,根节点的深度为0,但通常更常见的定义是根节点的深度为1)。
  对于任何一个节点,如果它是叶子节点(即没有子节点),那么它的深度就是它所在的层级。
  对于任何一个非叶子节点,它的深度是它左右子树中深度较大的那个子树的深度加1。

    A
   / \
  B   C
 / \
D   E

在这个二叉树中:
  根节点A的深度为1。
  节点B和C的深度为2(因为它们都在根节点的下一层)。
  节点D和E的深度为3(因为它们是最远的叶子节点,从根节点A需要经过两层才能到达)。

因此,这个二叉树的深度是3。

在iris数据集上,设置max_depth=1是完全有效的,
设置max_depth=2时,日志就会输出树过高了
因此在AI中max_depth是不包含树的叶子节点的,因为叶子节点被用来存储数据,表示分类结果了

相当于上面的二叉树真正的部分只有A,B,C
    A
   / \
  B   C
 / \   \
0   1   0
其中最后一层的叶子节点更多的是为了表示分类的结果

树的构建
- root为第一个分裂节点,对应一个特征
- max_depth指从root到叶子节点的 最大路径长度上的节点个数,不包括叶子节点
- 叶子节点输出的是分类结果

# 初始化LightGBM模型
params = {
    'objective': 'multiclass',  # 多分类问题
    'num_class': 3,             # 类别数
    'metric': 'multi_logloss',   # 评估指标
    'max_depth':1,
    'verbosity':1  #0-error,1-info
}

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=10,  # 迭代次数
                valid_sets=test_data)


[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000087 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 86
[LightGBM] [Info] Number of data points in the train set: 105, number of used features: 4
[LightGBM] [Info] Start training from score -1.219973
[LightGBM] [Info] Start training from score -1.043042
[LightGBM] [Info] Start training from score -1.043042

# 初始化LightGBM模型
params = {
    'objective': 'multiclass',  # 多分类问题
    'num_class': 3,             # 类别数
    'metric': 'multi_logloss',   # 评估指标
    'max_depth':3,
    'verbosity':1  #0-error,1-info
}

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=10,  # 迭代次数
                valid_sets=test_data)  # 提前停止的轮数


[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000080 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 86
[LightGBM] [Info] Number of data points in the train set: 105, number of used features: 4
[LightGBM] [Info] Start training from score -1.219973
[LightGBM] [Info] Start training from score -1.043042
[LightGBM] [Info] Start training from score -1.043042
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
....

算法在尝试分裂节点时未能找到任何具有正增益的分裂。
增益是衡量分裂好坏的指标,通常基于目标函数的改善程度。

这里的“best gain: -inf”表示最佳增益是负无穷大,
实际上这意味着没有任何分裂能够改善当前模型的性能(或者至少算法未能找到这样的分裂)。

这里lightgbm认为这种情况下的max_depth为1,即不包括root与叶节点,
直白地说,就是总共做了一次特征选择,得到的节点对应的叶节点就直接是分类结果了





num_leaves

num_leaves ,
- default = 31,
- type = int,
- aliases: num_leaf, max_leaves, max_leaf, max_leaf_nodes,
- constraints: 1 < num_leaves <= 131072

  max number of leaves in one tree

  只是一棵树中叶子节点的个数

使用lightgbm在breast_cancer数据集上训练时,breast_cancer的数据有30个特征,
下面是输入lightgbm的参数,
params = {
    'boosting': 'gbdt',  # 提升类型
    'objective': 'binary',  # 任务类型
    'metric': {'binary_logloss', 'auc'},  # 评估指标
    'num_leaves': 31,  # 叶子节点数 ,这是回归问题,有30个特征列
    'learning_rate': 0.05,  # 学习率
    'feature_fraction': 0.9,  # 特征采样比例
    'bagging_fraction': 0.8,  # 数据采样比例
    'bagging_freq': 5,  # 每5轮进行一次bagging
    'verbose': 0,  # 控制训练时的输出信息
    'max_depth':2
}
但为什么数据集有30个特征,但num_leaves的值却是30+1,而不是30?
叶子节点的个数与特征的个数有关系吗?

在使用LightGBM时,num_leaves 参数的设置与数据集中特征的数量没有直接关系。
num_leaves 参数指定的是模型中的叶子节点数,
这是一个影响模型复杂度和拟合能力的参数。

叶子节点数是决策树中最终的节点数,每个叶子节点代表了一个决策结果。
在LightGBM中,通常需要将 num_leaves 设置得比特征数多一些,
因为模型会尝试通过创建更多的分支来捕捉数据中的复杂关系。

在breast_cancer的例子中,尽管数据集有30个特征,
但设置 num_leaves 为31是合理的,
因为这样可以允许模型有足够的灵活性来捕捉数据中的非线性关系,
而不会过度限制模型的复杂度。

实际上,num_leaves 的选择通常需要通过交叉验证等调参技术来确定,以找到最佳的模型性能。

总结来说,num_leaves 的选择与特征的数量无关,而是与模型的复杂度和拟合能力有关。在实际应用中,通常需要调整这个参数来优化模型性能。

num_leaves 是 LightGBM 中一个重要的参数,它决定了每棵树中叶子节点的数量。
这个参数的选择对模型的性能有很大影响,
因此通常需要通过交叉验证等调参技术来确定最佳值。

以下是一个使用交叉验证来调整 num_leaves 参数的例子:

准备数据:
首先,你需要准备你的数据集,并将其分为训练集和测试集。

定义参数范围:
确定你想要测试的 num_leaves 的范围。例如,你可以测试从 10 到 100 的不同值。

设置交叉验证:
使用交叉验证来评估不同 num_leaves 值下的模型性能。
你可以使用 LightGBM 的 cv 函数来进行交叉验证。

训练模型并评估性能:
对于每个 num_leaves 的值,训练模型并使用交叉验证来评估其性能。
记录每个值下的性能指标(如准确率、AUC等)。

选择最佳参数:
根据交叉验证的结果,选择性能最佳的 num_leaves 值。

使用最佳参数训练最终模型:
使用选定的 num_leaves 值来训练你的最终模型,并在测试集上评估其性能。

以下是一个简单的代码示例,展示了如何使用 LightGBM 的 cv 函数来进行交叉验证,并找到最佳的 num_leaves 值:

import lightgbm as lgb
from sklearn.model_selection import train_test_split
import numpy as np

# 加载数据
# X_train, X_test, y_train, y_test = ... # 你的数据集

# 定义参数范围
num_leaves_values = list(range(10, 101, 10))  # 从10到100,步长为10

# 设置交叉验证参数
params = {
    'boosting_type': 'gbdt',
    'objective': 'binary',
    'metric': 'binary_logloss',
    'verbose': -1
}
cv_results = []

# 进行交叉验证
for num_leaves in num_leaves_values:
    params['num_leaves'] = num_leaves
    cv_result = lgb.cv(params, train_set, num_boost_round=100, nfold=5, seed=42, stratified=False)
    cv_results.append(cv_result['binary_logloss-mean'][-1])

# 找到最佳 num_leaves 值
best_num_leaves = num_leaves_values[np.argmin(cv_results)]
print(f'Best num_leaves: {best_num_leaves}')

# 使用最佳参数训练最终模型
params['num_leaves'] = best_num_leaves
train_set = lgb.Dataset(X_train, label=y_train)
model = lgb.train(params, train_set, num_boost_round=100)

在这个例子中,我们首先定义了一个 num_leaves 的值范围,
并使用 LightGBM 的 cv 函数来进行交叉验证。

然后,我们找到具有最低 logloss 的 num_leaves 值,
并使用它来训练最终模型。

注意,你需要根据你的数据集和任务来调整这个示例中的代码。


# 设置参数
# binary, binary log loss classification (or logistic regression)
params = {
    'boosting': 'gbdt',  # 提升类型
    'objective': 'binary',  # 任务类型
    'metric': {'binary_logloss', 'auc'},  # 评估指标
    'num_leaves': 4,  # 叶子节点数 ,这是回归问题,有30个特征列
    'learning_rate': 0.05,  # 学习率
    'feature_fraction': 0.9,  # 特征采样比例
    'bagging_fraction': 0.8,  # 数据采样比例
    'bagging_freq': 5,  # 每5轮进行一次bagging
    'verbose': 0,  # 控制训练时的输出信息
    'max_depth':2
}

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=20,
                valid_sets=test_data)


accuracy为准确度,num_leaves从4-40,accuracy皆为0.96





# 设置参数
# binary, binary log loss classification (or logistic regression)
params = {
    'boosting': 'gbdt',  # 提升类型
    'objective': 'binary',  # 任务类型
    'metric': {'binary_logloss', 'auc'},  # 评估指标
    'num_leaves': 4,  # 叶子节点数 ,这是回归问题,有30个特征列
    'learning_rate': 0.05,  # 学习率
    'feature_fraction': 0.9,  # 特征采样比例
    'bagging_fraction': 0.8,  # 数据采样比例
    'bagging_freq': 5,  # 每5轮进行一次bagging
    'verbose': 0,  # 控制训练时的输出信息
    'max_depth':2
}

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=20,
                valid_sets=test_data)

在LightGBM(Light Gradient Boosting Machine)中,
num_boost_round参数指的是算法将执行的提升(boosting)轮次的数量。

提升算法是一种集成学习技术,它通过结合多个弱学习器(通常是决策树)来形成一个强学习器。
每一轮(round)中,算法都会根据当前模型的预测误差来构建一个新的弱学习器,
并将其添加到已有的模型集合中,以此来减少总体误差。

每次计算误差并进行弥补,就是一次提升

num_boost_round参数直接控制了这一过程将进行多少轮。
这个参数的选择对于LightGBM模型的性能至关重要。

如果设置得太低,模型可能没有足够的学习能力,导致欠拟合(underfitting);
如果设置得太高,模型可能会在训练数据上表现过好(即过拟合,overfitting),
但在未见过的数据上表现不佳。


为了确定最佳的num_boost_round值,
通常可以使用交叉验证(cross-validation)技术,如LightGBM的cv函数,来评估不同轮次下的模型性能。
通过这种方法,可以找到既能有效减少训练误差又不会导致过拟合的最佳轮次数。

此外,还有一些其他的方法可以辅助确定num_boost_round的值,
比如使用早停法(early stopping)。

早停法会在验证误差开始增加时停止训练,这有助于防止过拟合,并自动确定一个合适的轮次数。

在LightGBM中,可以通过设置early_stopping_rounds参数来启用早停法。






num_boost_round在LightGBM中可以理解为训练次数,
每次训练都在前一次训练的基础上进行一次“提升”(boosting)。

在LightGBM中,这种“提升”是通过构建多个弱学习器(通常是决策树)
并将它们组合成一个强学习器来实现的。
每进行一次迭代(iteration),算法都会根据当前模型的预测误差来构建一个新的弱学习器,
并将其添加到模型中,以此来减少总体误差。

具体来说,num_boost_round参数定义了算法将执行多少轮这样的迭代。
每一轮中,算法都会尝试找到最能减少当前误差的弱学习器,并将其加入到模型的集合中。

再观察每轮损失函数的输出,确定中止轮次

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, label = load_breast_cancer(return_X_y=True)

# 划分训练集和验证集(注意:cv函数内部也会进行划分,但这里为了演示先手动划分)
X_train, X_test, y_train, y_test = train_test_split(data, label, test_size=0.2, random_state=42)

# 转换为LightGBM的Dataset格式
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 设置LightGBM的参数
params = {
    'objective': 'binary',  # 这是一个二分类问题
    'metric': 'binary_logloss',  # 使用对数损失作为评估指标
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.9,
    'bagging_fraction': 0.8,
    'bagging_freq': 5,
    'verbose': -1
}

# 执行交叉验证
# 注意:cv函数中的num_boost_round参数是可选的,如果不设置,则默认使用足够多的轮次来展示所有可能的性能变化
# 我们这里设置一个相对较小的值来演示,但实际应用中可能需要更大的值
num_boost_round = 100
cv_results = lgb.cv(params, train_data, num_boost_round=num_boost_round, nfold=5, stratified=True, metrics=['binary_logloss'])

在上面的代码中,我使用了train_test_split来手动划分训练集和测试集,但这主要是为了演示。
在cv函数中,LightGBM会自动进行数据的划分和验证。我们设置了nfold=5来进行5折交叉验证

cv_results
'valid binary_logloss-mean': [0.6222439454303654,
  0.5901559055091102,
  0.5594823498338173,
  0.5326953814320516,
  0.5076526757696538,
  0.48575086649057714,
  0.4638189274940265,
  0.4431983400558625,
  0.42484857168317536,
  0.40832521785975145,
  0.392868313427862,
  0.37944539191633525


num_boost_round设置为100,就是训练/迭代100个轮次,
选择损失函数最小的轮次,再去训练一个最优模型

# 输出交叉验证的结果 ,这里假定最小的就是最优的
print('Best iteration:', len(cv_results['valid binary_logloss-mean']) - 1)
print(cv_results['valid binary_logloss-mean'][-1])

# 根据交叉验证的结果,我们可以选择一个合适的num_boost_round来训练最终的模型
# 例如,我们可以选择使验证误差最小的那个轮次
best_iteration = len(cv_results['valid binary_logloss-mean']) - 1

# 然后,使用最佳迭代次数来训练模型(这里只是演示,实际上你可能需要再次训练模型)
# gbm = lgb.train(params, train_data, num_boost_round=best_iteration)

# 注意:这里的test_data和y_test只是用于演示,实际上在交叉验证过程中我们不会用到它们
# 交叉验证会自动从train_data中划分出验证集来评估模型的性能

注意事项

上面的是理论,实际中,模型的准确率未必会随损失的下降而上升,

在乳腺癌数据集上,损失函数在100轮次以内持续下降,
但准确率在20个轮次后就不再提升了,最终需要的还是准确率

也就是说,后面构建的80多个决策树是多余的



lightgbm算法中feature_fraction参数,feature_fraction=0.9,是对特征进行随机采样90%,还是先将特征按重要性排序,只取重要的前90%?

fraction 英/ˈfrækʃn/ 美/ˈfrækʃn/
n. 小部分;分数;小数;少量;一点儿
fract 打碎 + -ion 行为,状态

在LightGBM算法中,feature_fraction 参数是用来进行特征子采样的,
其作用是随机选择部分特征(即特征列)来训练每一棵树,
以此达到提高模型泛化能力的效果,并可能减少过拟合。

当设置 feature_fraction=0.9 时,它意味着在构建每一棵树时,
算法会随机选择大约90%的特征来进行树的分裂操作,而不是全部特征。

重要的是要理解,这个随机选择是无差别的,并不考虑特征的重要性。
也就是说,LightGBM不会先对特征进行重要性排序,然后只选择前90%重要的特征。
相反,它会从所有特征中随机选取大约90%的特征来训练每一棵树。

特征重要性排序通常是在模型训练完成后,通过查看模型给出的特征重要性分数来确定的,
这有助于理解哪些特征对模型预测的贡献最大。

但在训练过程中,特别是使用像 feature_fraction 这样的正则化参数时,
LightGBM并不依赖于特征的重要性排序来做出选择。

lightgbm中feature_fraction=0.9,在训练每棵树时会随机90%的特征,可是,lightgbm在构建决策树时,不是使用了所有的特征吗?如果只选择90%,那岂不是有些决策树无法被训练?

在LightGBM中,feature_fraction 参数
确实用于在训练每棵树时随机选择一部分特征(在这个例子中是90%),

但这并不意味着只有这些被选中的特征会被用于构建整棵树,
也不意味着其他特征被完全忽略或导致某些决策树无法被训练。

实际上,这个过程是在每次迭代(即每棵树的构建)中独立进行的,
目的是增加模型的多样性和泛化能力。


以下是关于 feature_fraction 参数的详细解释:

随机特征选择:
在每次迭代开始时,LightGBM会根据 feature_fraction 的值随机选择一部分特征。
这意味着,虽然每次迭代可能只使用了全部特征的一个子集,
但不同的树可能会使用到不同的特征子集。

特征利用:
尽管只有部分特征被选中,但这些被选中的特征会充分参与当前树的构建过程。
也就是说,在构建当前树时,算法会使用这些被选中的特征来寻找最佳分裂点,
并据此构建树的结构。

多样性和泛化能力:
通过随机选择特征,LightGBM能够构建出具有不同结构和特征偏好的树,
从而增加整个模型的多样性。
这种多样性有助于模型更好地适应不同的数据分布,提高模型的泛化能力。

整体训练过程:
在整个训练过程中,每棵树都会经历这样的特征选择过程。
虽然每棵树可能只使用了部分特征,但所有树共同构成了最终的模型,
该模型能够综合利用所有特征的信息进行预测。

避免过拟合:
feature_fraction 参数还有助于避免过拟合。
通过限制每棵树可以使用的特征数量,
模型不会过于依赖某些特定的特征组合,从而提高了模型的稳健性。

综上所述,feature_fraction=0.9 在LightGBM中意味着在训练每棵树时会随机选择90%的特征,
但这并不意味着只有这些特征会被用于构建整棵树或导致某些决策树无法被训练。
相反,这是一个正则化手段,旨在提高模型的多样性和泛化能力。

lightgbm中feature_fraction=0.9,在训练每棵树时会随机90%的特征,Lightgbm会构建多棵树吗?这多棵树整体使用了所有的特征?有参数可以控制构建多少棵树吗?还是说构建多少棵树,是由lightgbm内部自己决定的?

在LightGBM中,feature_fraction=0.9 的设置
确实意味着在训练每棵树时会随机选择90%的特征进行树的构建。
关于LightGBM构建多棵树的相关问题,可以归纳如下:

1. LightGBM会构建多棵树吗?

是的,LightGBM会构建多棵树。
LightGBM是一种基于梯度提升框架的算法,它通过迭代地构建多棵决策树来形成一个强学习器。
每棵树都是基于之前树的预测残差进行构建的,旨在逐步减少预测误差。

2. 这多棵树整体使用了所有的特征吗?

不,整体而言并不一定会使用到所有的特征。
虽然每棵树在构建时都会随机选择部分特征(根据feature_fraction的设置),
但不同的树可能会选择到不同的特征子集。

因此,在整个模型的训练过程中,虽然每棵树只使用了部分特征,
但所有树共同构成的模型可能会覆盖到大部分甚至全部的特征,
具体取决于feature_fraction的值、树的数量以及数据的特征数量。

3. 有参数可以控制构建多少棵树吗?

是的,有参数可以控制构建多少棵树。
在LightGBM中,这个参数通常是num_boost_round
(在一些版本的LightGBM中也可能是n_estimators,两者作用相同)。

num_boost_round指定了梯度提升过程中要构建的树的数量,即算法的迭代次数。
增加这个值通常可以提高模型的性能,但也会增加过拟合的风险和计算成本。


4. 构建多少棵树是由LightGBM内部自己决定的吗?

不是,构建多少棵树是由用户通过参数设置的。
用户需要根据具体的数据集和任务需求来选择合适的树的数量。
虽然LightGBM内部有一些机制(如早停法early_stopping_rounds)来帮助用户自动确定最佳的迭代次数,
但最终的决定权还是在用户手中。

用户可以通过调整num_boost_round(或n_estimators)参数来控制构建多少棵树。

综上所述,LightGBM通过迭代地构建多棵树来形成一个强学习器,
每棵树在构建时会根据feature_fraction的设置随机选择部分特征。

用户可以通过设置num_boost_round(或n_estimators)参数来控制构建多少棵树。



在LightGBM算法中,`bagging_fraction` 参数指的是数据采样。
具体来说,`bagging_fraction` 表示每次构建树模型时
从原始训练数据集中随机抽取的数据比例(有放回地抽样)。

这是一种通过引入随机性来减少过拟合的方法。

参数含义:
- `bagging_fraction`:
表示每次迭代构建树模型时所使用的训练样本占全部训练样本的比例。
例如,如果设置为 0.8,则意味着每次构建树时只使用 80% 的训练样本进行训练。

示例说明:
- 当 `bagging_fraction=0.9` 时,表示每次构建树模型时将
从原始训练数据集中随机抽取 90% 的数据样本用于训练该树。
这种做法可以增加模型的多样性,并有助于提高模型的泛化能力。

注意事项:
- 通常与 `bagging_freq` 参数一起使用。
`bagging_freq` 指定每多少次迭代执行一次 bagging(数据采样)操作。
例如,如果 `bagging_freq=2`,则表示每两次迭代执行一次 bagging。

总结:
在 LightGBM 中,`bagging_fraction` 是一个非常重要的参数,
它通过控制每次迭代时
使用的训练数据量来帮助模型更好地泛化到未见过的数据上。
当设置为小于 1 的值时,可以有效降低过拟合的风险。



在内存不足的情况下,force_col_wise为True,有助于模型训练

# 创建LightGBM数据集,并指定分类特征
train_data = lgb.Dataset(X_train, label=y_train, categorical_feature=cat_features)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 设置参数并训练模型
params = {
    'objective': 'binary',
    'metric': 'binary_logloss',
    'boosting_type': 'gbdt',
    'max_depth': 3,
    'num_leaves': 3,
    'max_bin':3,
    'min_gain_to_split':0,
    'min_data_in_leaf':10,
    'force_col_wise':True}
lgb_model = lgb.train(params, train_data, num_boost_round=1,  valid_sets=[test_data],)



 
皆是整数 
min_child_samples为样本个数,默认值 20 
min_data_in_leaf = min_child_samples*每个样本的维度 ,默认值 20 

min_child_samples

 
一、参数含义
min_child_samples参数,也被称为min_child_weight(在某些上下文中),
它表示每个叶子节点所需的最小样本数(或在某些实现中,是最小子节点中的所有样本权重总和)。
这个参数用于控制树的生长过程,以防止过拟合。
当某个子节点的样本数量(或权重和)小于min_child_samples时,该节点将不会继续拆分。
通过调整这个参数,可以控制树的深度和复杂度,进而影响模型的泛化能力。

二、默认值
min_child_samples参数的默认值在不同的资料和版本中可能略有不同,但根据LightGBM的官方文档和多数可靠资料,其默认值通常为20。这个默认值旨在在模型的复杂度和性能之间找到一个平衡点,以适应大多数数据集和任务。

三、参数调整的影响
防止过拟合:较大的min_child_samples值可以限制树的深度,减少模型的复杂度,从而降低过拟合的风险。
然而,如果设置得过大,可能会导致模型欠拟合,因为树可能无法充分捕捉到数据中的特征。

提高训练速度:较大的min_child_samples值可以减少树节点的数量,从而降低模型的计算复杂度,提高训练速度。

影响模型性能:min_child_samples的值需要根据具体的数据集和任务来调整。
在调整时,可以观察模型在验证集上的性能变化,以找到最佳的参数值。

综上所述,min_child_samples参数在LightGBM中扮演着重要的角色,它影响着模型的复杂度和泛化能力。
了解其含义和默认值,并根据实际情况进行合理调整,是提升LightGBM模型性能的关键步骤之一。

  

min_data_in_leaf

 
一、参数含义
min_data_in_leaf参数表示一个叶子节点上包含的最少样本数量。它是处理leaf-wise树的过拟合的重要参数。将其设为较大的值,可以避免生成一个过深的树,但也可能导致欠拟合。相反,如果设置得太小,则可能会增加过拟合的风险,因为树可能会变得过于复杂,捕捉到数据中的噪声。

二、默认值
min_data_in_leaf参数的默认值在不同的资料和版本中可能有所不同。但根据LightGBM的官方文档和多数可靠资料,其默认值通常为20。这个默认值是一个相对保守的选择,旨在在模型的复杂度和泛化能力之间找到一个平衡点。

三、调参建议
在实际应用中,min_data_in_leaf参数的值需要根据具体的数据集和任务来调整。以下是一些调参建议:

数据规模和分布:如果数据集很大且分布较为均匀,可以适当增加min_data_in_leaf的值,以减少树的深度,提高模型的泛化能力。相反,如果数据集较小或分布不均匀,可能需要减小该值以避免欠拟合。
模型性能:在调整min_data_in_leaf时,可以观察模型在验证集上的性能变化。如果模型过拟合严重,可以尝试增加该值;如果模型欠拟合,则可以尝试减小该值。
与其他参数的协同:min_data_in_leaf参数通常需要与其他参数(如max_depth、num_leaves、feature_fraction等)协同调整,以达到最佳的模型性能。
综上所述,min_data_in_leaf参数在LightGBM中扮演着重要的角色,它影响着模型的复杂度和泛化能力。了解其含义和默认值,并根据实际情况进行合理调整,是提升LightGBM模型性能的关键步骤之一。

    


😊

**min_child_samples**:

min_child_samples 是 LightGBM 中的一个 hyperparameter,
用于控制每个叶子节点(leaf node)中的最小样本数。
这个参数的作用是防止过拟合(overfitting),因为如果每个叶子节点中的样本数太少,模型可能会过度拟合训练数据。

在 LightGBM 中,min_child_samples 是一个整数参数,表示每个叶子节点中的最小样本数。
如果一个叶子节点中的样本数小于这个值,LightGBM 将不会对该叶子节点进行分裂。


**min_data_in_leaf**:

min_data_in_leaf 是 LightGBM 中另一个 hyperparameter,
用于控制每个叶子节点中的最小数据量。
这个参数的作用是防止过拟合和提高模型的泛化能力。

在 LightGBM 中,min_data_in_leaf 是一个浮点数参数,表示每个叶子节点中的最小数据量。
如果一个叶子节点中的数据量小于这个值,LightGBM 将不会对该叶子节点进行分裂。


**区别**:

min_child_samples 和 min_data_in_leaf 都是用来防止过拟合的 hyperparameters,但是它们的区别在于:

* min_child_samples 是根据样本数来控制叶子节点的分裂,
而 min_data_in_leaf 是根据数据量来控制叶子节点的分裂。

* min_child_samples 是一个整数参数,而 min_data_in_leaf 是一个浮点数参数。

在实际应用中,如果你想控制叶子节点中的样本数,可以使用 min_child_samples。
如果你想控制叶子节点中的数据量,可以使用 min_data_in_leaf。
通常情况下,min_child_samples 和 min_data_in_leaf 都需要同时使用,以避免过拟合和提高模型的泛化能力。


`min_child_samples` 控制的是每个叶子节点中的最小样本个数。
也就是说,在 LightGBM 中,每个叶子节点都需要包含至少 `min_child_samples` 个样本。

如果一个叶子节点中的样本个数少于 `min_child_samples`,
那么该叶子节点将被合并到父节点中,以避免过拟合。

`min_data_in_leaf` 控制的是
每个叶子节点中的最小数据量(也就是样本个数乘以每个样本的特征维度)。
这个参数的作用是防止每个叶子节点中的数据量太小,从而避免过拟合。

在 LightGBM 中,`min_data_in_leaf` 是一个相对的概念,它取决于每个样本的特征维度。
如果每个样本的特征维度很高,`min_data_in_leaf` 就需要相对较大,
以确保每个叶子节点中的数据量足够大。

因此,`min_child_samples` 控制的是样本个数,
而 `min_data_in_leaf` 控制的是数据量(样本个数乘以每个样本的特征维度)。
这两个参数都可以用来防止过拟合,但是它们的作用机理不同。


1. `min_child_samples`(别名:`min_data_per_leaf`, `min_data`, `min_child_samples`):
这个参数表示一个叶子节点上包含的最少样本数量。
它可以用来处理过拟合。
这个参数的值取决于训练数据的样本个数和`num_leaves`参数。
将其设置得较大可以避免生成一个过深的树,但有可能导致欠拟合。

2. `min_data_in_leaf`(别名:`min_sum_hessian_in_leaf`, `min_sum_hessian_per_leaf`,
 `min_sum_hessian`, `min_hessian`, `min_child_weight`):
 这个参数表示一个叶子节点上的最小hessian之和。
 它类似于`min_child_samples`,也可以用来处理过拟合。
 `min_sum_hessian_in_leaf`参数是使一个结点分裂的最小海森值之和,
 这个参数的值越高,越可能减少过拟合。

 在LightGBM中,节点分裂的海森值(Hessian)是指在梯度提升树(Gradient Boosting Trees)算法中,
 用于衡量模型在特定点的曲率的二阶导数的总和。
 在决策树的上下文中,海森值通常与每个特征在特定节点的二阶导数相关联,它反映了数据在该特征上的分布情况。
 在LightGBM中,`min_sum_hessian_in_leaf` 参数定义了一个叶子节点上的最小海森值之和,
 这个参数用来控制模型的复杂度,以减少过拟合的风险。

 具体来说,`min_sum_hessian_in_leaf` 参数的作用是确保在进行节点分裂时,
 只有当叶子节点上的海森值之和达到这个阈值时,才会考虑分裂。
 如果一个叶子节点上的海森值之和小于这个参数设定的值,那么这个节点就不会被分裂,
 从而避免了在数据较少或信息不足的区域创建过于复杂的模型。

 通过设置一个较高的`min_sum_hessian_in_leaf`值,可以增加模型的正则化强度,
 减少模型对训练数据的敏感度,从而降低过拟合的可能性。


min_gain_to_split


分裂最小增益
- 增益低于该值则不再分裂

执行分裂所需的最小增益。建议值范围: 0-10,值越大模型越简单,可能欠拟合,值越小模型越复杂,可能过拟合。





# 初始化LightGBM模型
params = {
    'objective': 'multiclass',  # 多分类问题
    'num_class': 3,             # 类别数
    'metric': 'multi_logloss',   # 评估指标
    'num_threads': 4
}

# 创建数据集
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=3,  # 迭代次数
                valid_sets=test_data)  # 提前停止的轮数

LightGBM利用OpenMP来并行化多个操作,通过num_threads参数可以控制LightGBM使用的最大线程数。

默认情况下,LightGBM会遵循OpenMP的默认行为,即使用与实际CPU核心数相同的线程数,

或者如果设置了环境变量OMP_NUM_THREADS,则使用该变量的值。

为了获得最佳性能,用户可以将此参数设置为可用的实际CPU核心数。

因此,在使用LightGBM进行模型训练时,可以根据实际的硬件资源和需求,

通过调整num_threads参数来合理地分配CPU资源,以达到更好的训练效果和效率。


Lightgbm参数num_threads的默认值是0。
在Lightgbm中,num_threads参数用于指定运行时的线程数,0表示使用OpenMP中的默认线程数。
这个参数可以帮助用户根据计算资源调整模型的训练速度,
但需要注意的是,增加线程数虽然可以加快训练速度,但也可能增加计算资源的消耗。
因此,在实际应用中,用户需要根据自己的计算资源和需求来合理设置这个参数。





参数调用示例


在使用乳腺癌数据集(如常见的Breast Cancer Wisconsin (Diagnostic) 数据集)来训练LightGBM模型时,

lambda_l1(也称为reg_alpha)和lambda_l2(也称为reg_lambda)是两个重要的正则化参数,
它们有助于控制模型的复杂度,防止过拟合。

lambda_l1(reg_alpha)


参数说明:lambda_l1是L1正则化项的权重。
L1正则化会对模型的权重(在LightGBM中,可以理解为叶子节点的分数)进行稀疏化处理,
即使得一些权重变为零,从而减少模型中的不必要特征。

作用:增加lambda_l1的值会增强L1正则化的效果,有助于减少特征的数量,使模型更加简洁。
这在高维数据中尤其有用,因为可以帮助模型筛选出最重要的特征。

建议值:在乳腺癌数据集中,由于特征数量相对较少(通常不超过30个),
lambda_l1的值可以从较小的值开始尝试,如0.01或0.1。
然后,可以通过交叉验证等方法来找到最优的值。

影响:lambda_l1值越大,模型对权重的惩罚越大,可能导致更多的权重变为零,从而简化模型。
但过高的值可能导致模型欠拟合,即模型在训练集和验证集上的表现都较差。



lambda_l2(reg_lambda)


参数说明:lambda_l2是L2正则化项的权重。
L2正则化会对模型的权重进行平滑处理,即使得权重的绝对值不会太大,从而减少模型的波动性和过拟合的风险。

作用:增加lambda_l2的值会增强L2正则化的效果,有助于使模型的权重更加平滑和稳定。

建议值:与lambda_l1类似,lambda_l2的值也可以从较小的值开始尝试,如0.01或0.1。
然后,通过交叉验证等方法来找到最优的值。
在乳腺癌数据集中,由于数据相对较少且特征数量不多,因此可能需要相对较小的lambda_l2值来避免过度正则化。

影响:lambda_l2值越大,模型对权重的惩罚越大,权重值会趋向于零但不一定为零(与L1正则化不同)。
这有助于减少模型的复杂性,但过高的值同样可能导致模型欠拟合。

示例
假设我们正在使用LightGBM对乳腺癌数据集进行分类任务,以下是一个简化的参数设置示例:


import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

# 加载乳腺癌数据集
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.DataFrame(data.target,columns=['target'])

X_train, X_test, y_train,  y_test = train_test_split(X, y, test_size=0.2, random_state=42)


from lightgbm import LGBMClassifier

# 初始化模型
model = LGBMClassifier(
    boosting_type='gbdt',
    objective='binary',
    num_leaves=31,
    max_depth=-1,
    learning_rate=0.1,
    n_estimators=100,
    lambda_l1=0.1,  # L1正则化项权重
    lambda_l2=0.1,  # L2正则化项权重
    min_data_in_leaf=20,
    bagging_fraction=0.8,
    feature_fraction=0.9,
    verbose=-1
)

# 训练模型(假设X_train和y_train是已经准备好的训练数据和标签)
model.fit(X_train, y_train)






首先,params字典需要包含模型的配置参数,包括objective设置为二分类参数(通常是'binary')。
其次,train_data和test_data需要被正确地定义和准备为LightGBM的数据集格式。
此外,valid_sets通常用于监控验证集上的性能,
因此应该传入一个验证数据集,而不是测试数据集
(在机器学习中,我们通常保留一个独立的测试集来评估最终模型的性能,而不是在训练过程中使用它)。


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 = data.data
y = data.target

# 将数据集拆分为训练集和验证集(注意:这里不使用测试集,而是保留一个验证集)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

# 将数据转换为LightGBM的数据集格式
train_data = lgb.Dataset(X_train, label=y_train)
val_data = lgb.Dataset(X_val, label=y_val, reference=train_data)

# 设置模型参数
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': -1,
    'lambda_l1': 0.1,  # L1正则化项权重
    'lambda_l2': 0.1   # L2正则化项权重
}

# 训练模型
num_boost_round = 100  # 迭代次数(树的数量)
evals_result = {}  # 用于存储评估结果
bst = lgb.train(params,
                train_data,
                num_boost_round=num_boost_round,
                valid_sets=[train_data, val_data],
                valid_names=['train', 'valid'])  # 提前停止,如果验证集上的性能在10轮内没有提升

# 打印评估结果
print('Best iteration:', bst.best_iteration)
print('Eval results:', evals_result)

# 预测并评估模型(这里仅作为示例,通常我们会在一个独立的测试集上进行评估)
y_pred = bst.predict(X_val, num_iteration=bst.best_iteration)
y_pred_binary = [1 if pred > 0.5 else 0 for pred in y_pred]
accuracy = accuracy_score(y_val, y_pred_binary)
print('Validation accuracy:', accuracy)


在这个示例中,我使用了sklearn.datasets中的load_breast_cancer函数来加载乳腺癌数据集,
并将其拆分为训练集和验证集。

然后,我设置了LightGBM的参数,包括objective为'binary'以进行二分类任务,
以及L1和L2正则化项的权重。

模型使用lgb.train函数进行训练,并监控训练集和验证集上的性能。
最后,我打印了最佳迭代次数、评估结果以及在验证集上的准确率。

请注意,在实际应用中,
您应该保留一个独立的测试集来评估最终模型的性能,而不是在训练过程中使用验证集。
此外,您可能还需要通过交叉验证等方法来进一步调优模型参数。






import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.datasets import make_classification

# 生成一个不平衡的分类数据集
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, weights=[0.1, 0.9], random_state=42)

# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建LGBMClassifier实例,并设置类别权重
# 由于y中的类别标签是0和1,我们为这两个类别设置不同的权重
# 这里我们假设想要更多地关注类别0(即少数类),所以为其设置更高的权重
class_weight = {0: 10, 1: 1}  # 你可以根据需要调整这些权重值

model = lgb.LGBMClassifier(class_weight=class_weight, num_leaves=31, learning_rate=0.1, n_estimators=100, random_state=42)

# 训练模型
model.fit(X_train, y_train)

# 预测测试集
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")



Accuracy: 0.9250

下面是不加权


model = lgb.LGBMClassifier(num_leaves=31, learning_rate=0.1, n_estimators=100, random_state=42)

# 训练模型
model.fit(X_train, y_train)

# 预测测试集
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")


Accuracy: 0.9350

这里不加权效果更好,这样跟生成的数据有关,所以并不一定加权就好 

model = lgb.LGBMClassifier(class_weight='balanced', num_leaves=31, learning_rate=0.1, n_estimators=100, random_state=42)

# 训练模型
model.fit(X_train, y_train)

# 预测测试集
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")

Accuracy: 0.9250






lightgbm代码示例

import numpy as np
import lightgbm as lgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 加载数据
iris = load_iris()
X = iris.data
y = iris.target
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 初始化LightGBM模型
params = {
    'objective': 'multiclass',  # 多分类问题
    'num_class': 3,             # 类别数
    'metric': 'multi_logloss'   # 评估指标
}

# 创建数据集
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=100,  # 迭代次数
                valid_sets=test_data)  # 提前停止的轮数

# 预测
y_pred = gbm.predict(X_test)
# 将预测的概率转换为类别(最大概率的类别)
y_pred_classes = [int(np.argmax(line)) for line in y_pred]

# 评估
accuracy = accuracy_score(y_test, y_pred_classes)
print(f'Accuracy: {accuracy:.4f}')

Accuracy: 1.0000

sum(y_test== y_pred_classes)/len(y_test)
1.0

import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

from tpf.datasets import load_iris
X_train, y_train, X_test, y_test = load_iris()

# 模型定义
model = DecisionTreeClassifier(criterion="gini", max_depth=5)

# 训练
model.fit(X=X_train,y=y_train)

# 预测
y_pred=model.predict(X=X_test)

# 将预测的概率转换为类别(最大概率的类别)
# y_pred_classes = [int(np.argmax(line)) for line in y_pred]

# 评估
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.4f}')

Accuracy: 0.8667

sum(y_test== y_pred)/len(y_test)
0.8666666666666667

max_depth=5 不合理,但决策树超长会自动剪枝,所以结果一样







LGBMClassifier

 
from sklearn.datasets import make_classification
X,y = make_classification(n_samples=1000000,n_features=200,n_classes=2,)
  

 
import numpy as np
from lightgbm import LGBMClassifier

# 训练模型
model = LGBMClassifier(n_estimators=300,num_threads=4)
model.fit(X, y)

 
model.predict_proba(X)
    

 

    

 


 

  

 


多特征二分类

- 二分类问题,乳腺癌数据集,“0-正常”,“1-癌变”。
- 该数据集包含了多个与乳腺癌相关的特征,以及一个表示是否为恶性肿瘤的标签。

数据准备

import numpy as np
import pandas as pd
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, roc_auc_score, log_loss

# 加载乳腺癌数据集
data = load_breast_cancer()
X = data.data  # 特征
y = data.target  # 标签

# 将数据集划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

模型训练

# 设置LightGBM参数
params = {
    'objective': 'binary',  # 目标函数为二分类
    'metric': 'auc',  # 评估指标为AUC
    'num_leaves': 31,  # 叶子节点数
    'max_depth': 6,  # 树的最大深度
    'learning_rate': 0.02,  # 学习率
    'bagging_fraction': 0.8,  # 每次迭代时用的数据比例
    'feature_fraction': 0.8,  # 每次迭代中随机选择特征的比例
    'min_child_samples': 25,  # 一个叶子节点上数据的最小数量
    'verbose': -1  # 是否打印训练过程中的信息,-1表示不打印
}

# 训练LightGBM模型
model = lgb.LGBMClassifier(**params)
model.fit(X_train, y_train, eval_set=[(X_train, y_train), (X_test, y_test)],
          eval_metric=['auc', 'binary_logloss'])

模型评估

常用的评估指标包括准确率(accuracy)、ROC AUC分数和Log Loss等。

# 在测试集上进行预测
y_pred_prob = model.predict_proba(X_test)[:, 1]  # 预测为正类的概率
y_pred = model.predict(X_test)  # 预测类别

# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
roc_auc = roc_auc_score(y_test, y_pred_prob)
logloss = log_loss(y_test, y_pred_prob)

print(f'准确率: {accuracy:.4f}')
print(f'ROC AUC分数: {roc_auc:.4f}')
print(f'Log Loss: {logloss:.4f}')

准确率: 0.9591
ROC AUC分数: 0.9912
Log Loss: 0.1616





from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))

              precision    recall  f1-score   support

            0       0.95      0.94      0.94        63
            1       0.96      0.97      0.97       108

    accuracy                           0.96       171
    macro avg       0.96      0.95      0.96       171
weighted avg       0.96      0.96      0.96       171

这个报告是使用classification_report函数从scikit-learn库生成的,
用于评估二分类模型的性能。

报告中的各个字段含义如下:

precision(精确率)

precision 英/prɪˈsɪʒn/ 美/prɪˈsɪʒn/ n. 精确;准确;细致 adj. 精确的

精确率衡量的是模型预测为正类的样本中,真正为正类的比例。
对于类别0,精确率为0.95,
意味着在模型预测为类别0的样本中,有95%的样本实际上是类别0。

对于类别1,精确率为0.96,
意味着在模型预测为类别1的样本中,有96%的样本实际上是类别1。

recall(召回率)

召回率衡量的是所有真正为正类的样本中,被模型正确预测为正类的比例。

对于类别0,召回率为0.94,
意味着在所有实际为类别0的样本中,有94%被模型正确预测。

对于类别1,召回率为0.97,
意味着在所有实际为类别1的样本中,有97%被模型正确预测。

f1-score(F1分数)

F1分数是精确率和召回率的调和平均数,是两者的综合指标,用于衡量模型的整体性能。

对于类别0和类别1,F1分数分别为0.94和0.97,表示模型在这两个类别上的综合性能。

support(支持度)

支持度指的是每个类别在测试集中出现的样本数量。
类别0有63个样本,类别1有108个样本。

accuracy(准确率)

准确率衡量的是模型在所有样本上的预测准确性,
即正确预测的样本数占总样本数的比例。

这里准确率为0.96,
意味着模型在171个测试样本中正确预测了164个样本。

macro avg(宏平均)

宏平均是对所有类别的指标(精确率、召回率和F1分数)进行算术平均,
不考虑每个类别的样本数量。

这里的宏平均精确率、召回率和F1分数均为0.96,表明模型在两个类别上的性能相对均衡。

weighted avg(加权平均)

加权平均考虑了每个类别的样本数量,对每个类别的指标进行加权平均。

这里的加权平均精确率、召回率和F1分数也都是0.96,
由于类别1的样本数量多于类别0,
因此加权平均更多地反映了模型在类别1上的性能。

总的来说,这份报告表明模型在两个类别上的性能都相当出色,具有较高的精确率、召回率和F1分数。







指明分类列

import lightgbm as lgb
import pandas as pd
from sklearn.model_selection import train_test_split

# 将类别特征转换为category类型(这一步是可选的,但推荐执行,以明确指定字段类型)
cat_features = pc.col_type_trans.str_classification
data = pd_trans
for feature in cat_features:
    data[feature] = data[feature].astype('category')


# 删除训练不需要的字段
data.drop(columns=pc.col_type_trans.str_identity, inplace=True)  # 删除身份标识类型字段
data.drop(columns=pc.col_type_trans.date_type, inplace=True)     # 删除原始日期类型字段

#随机生成标签
np.random.seed(73)
y = np.random.randint(low=0,high=2,size=(data.shape[0]))

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建LightGBM数据集,并指定分类特征
# free_raw_data=False是因为在数据上设置部分列为category类型,此时lightgbm要求这个数据集不能被释放
train_data = lgb.Dataset(X_train, label=y_train, free_raw_data=False, categorical_feature=cat_features)
test_data = lgb.Dataset(X_test, label=y_test,  reference=train_data)

# 设置参数并训练模型
params = {
    'objective': 'binary',
    'metric': 'binary_logloss',
    'boosting_type': 'gbdt',
    'max_depth': 3,
    'num_leaves': 3,
    'max_bin':3,
    'min_gain_to_split':0,
    'min_data_in_leaf':10,
    'force_col_wise':True}
lgb_model = lgb.train(params, train_data, num_boost_round=1,  valid_sets=[test_data],)







# 将类别特征转换为category类型(这一步是可选的,但推荐执行,以明确指定字段类型)
cat_features = pc.col_type_trans.str_classification
data = pd_trans
for feature in cat_features:
    data[feature] = data[feature].astype('category')

# free_raw_data=False是因为在数据上设置部分列为category类型,此时lightgbm要求这个数据集不能被释放
train_data = lgb.Dataset(X_train, label=y_train, free_raw_data=False, categorical_feature=cat_features)










网格搜索

准备数据

首先,需要准备乳腺癌数据集。
乳腺癌数据集通常包含了多个样本,每个样本都有多个特征,
这些特征主要描述了细胞核的特性(如半径、质地、周长、面积等),
目标变量是样本是否为恶性肿瘤(标记为1)或良性肿瘤(标记为0)。

在Python中,可以使用sklearn.datasets中的load_breast_cancer函数来加载乳腺癌数据集。
以下是一个示例代码:

from sklearn.datasets import load_breast_cancer

# 加载乳腺癌数据集
data = load_breast_cancer()
X = data.data  # 特征数据
y = data.target  # 目标变量

划分数据集

为了进行模型训练和验证,需要将数据集划分为训练集和测试集。
通常,可以使用train_test_split函数来完成这一操作。
以下是一个示例代码:

from sklearn.model_selection import train_test_split

# 划分训练集和测试集,80%用于训练,20%用于测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)




from lightgbm import LGBMClassifier

# 定义LightGBM模型
model = LGBMClassifier()

设置网格搜索参数

网格搜索是一种在多个维度上搜索最优解的方法,
通过指定一组参数的候选值来搜索最优的参数组合。
以下是一个设置网格搜索参数的示例代码:

from sklearn.model_selection import GridSearchCV

# 定义参数候选值
param_grid = {
    'learning_rate': [0.05, 0.06, 0.07, 0.08, 0.09, 0.1],
    'n_estimators': [500, 600, 700, 800],
    'max_depth': range(2, 8)
}



# 初始化网格搜索对象
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5, scoring='accuracy', verbose=2)

# 执行网格搜索
grid_search.fit(X_train, y_train)

# 输出最优参数
print("Best parameters:", grid_search.best_params_)

# 使用最优参数训练模型
best_model = grid_search.best_estimator_

# 在测试集上进行预测
y_pred = best_model.predict(X_test)

# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)





一次只调整一组参数,并且输入的参数数据不要多,
因为网格搜索通常比较耗费内存,
当一次输入的参数比较好多时,内存往往是不够用的,这时性能就会变慢,长时间不出结果...
一次训练本来两三个小时能出结果的,经网格搜索这么一搞,两天不结出也是有可能的...

如果是一个参数一个参数地优化,
网格搜索的优势就弱了很多,会出现不如根据经验自己调整的现象...

如果是数据集小,几分钟就训练完了,用一下网格搜索还是比较方便的
但
网格搜索优化出来的参数,比不懂算法的人会好一些,
但多数不比过算法工程师根据经验调整而来的结果








特征重要性

使用特征重要性对特征进行评估,过滤不重要的特征


from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import pandas as pd

# 加载乳腺癌数据集
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)

# 数据集划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)






from lightgbm import LGBMClassifier

# 初始化LightGBM分类器
model = LGBMClassifier(
    num_leaves=31,
    learning_rate=0.05,
    n_estimators=2)

# 训练模型
model.fit(X_train, y_train)

评估特征重要性

# 获取特征重要性
importances = model.feature_importances_

# 将特征重要性与特征名称对应起来
feature_importances = pd.DataFrame({
    'feature': X.columns,
    'importance': importances
}).sort_values(by='importance', ascending=False)

print(feature_importances)

feature  importance
0               mean radius           3
21            worst texture           3
27     worst concave points           2
13               area error           2
6            mean concavity           2
7       mean concave points           2
20             worst radius           2
22          worst perimeter           1
1              mean texture           1
19  fractal dimension error           0
24         worst smoothness           0
...
...

选择重要特征
- 根据特征重要性,选择前N个重要的特征来重新训练模型。这里我们假设选择前10个重要特征:

# 选择前10个重要特征
top_features = feature_importances.head(10)['feature'].tolist()

# 提取这些特征对应的训练集和测试集
X_train_selected = X_train[top_features]
X_test_selected = X_test[top_features]

重新训练模型

# 重新初始化LightGBM分类器
model_selected = LGBMClassifier(num_leaves=31, learning_rate=0.05, n_estimators=3)

# 使用选择后的特征训练模型
model_selected.fit(X_train_selected, y_train)

评估模型性能

from sklearn.metrics import accuracy_score

# 在测试集上进行预测
y_pred_selected = model_selected.predict(X_test_selected)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred_selected)
print("Accuracy with selected features:", accuracy)

Accuracy with selected features: 0.6228070175438597

from sklearn.metrics import roc_auc_score

# 计算AUC
auc = roc_auc_score(y_test, y_pred_selected)
print(f"AUC: {auc:.4f}")

AUC: 0.5000

import lightgbm as lgb

# 创建LightGBM数据集
train_data = lgb.Dataset(X_train, label=y_train)

# 设置参数
params = {
    'objective': 'binary',
    'metric': 'binary_logloss',
    'boosting_type': 'gbdt'
}

# 训练模型
model = lgb.train(params, train_data, num_boost_round=3)

训练完成后,可以获取特征重要性并进行可视化。

import matplotlib.pyplot as plt

# 获取特征重要性
importance = model.feature_importance()
feature_names = X.columns

# 创建特征重要性的DataFrame
important_features = pd.DataFrame({'feature': feature_names, 'importance': importance})

# 按重要性排序
important_features = important_features.sort_values(by='importance', ascending=False)

# 可视化特征重要性
plt.figure(figsize=(10, 6))
plt.barh(important_features['feature'], important_features['importance'])
plt.xlabel('Importance')
plt.title('Feature Importance - LightGBM')
plt.show()

选择相对重要的特征并重新训练模型
- 可以选择前N个重要的特征来进行再次训练。例如,选择重要性最高的前10个特征。
- 对于乳腺癌这个数据集,top10与top20的效果一样


# 选择前10个重要特征
top_n = 10
selected_features = important_features['feature'].head(top_n).values

# 使用选择的特征进行训练和测试
X_train_selected = X_train[selected_features]
X_test_selected = X_test[selected_features]

# 重新训练模型
train_data_selected = lgb.Dataset(X_train_selected, label=y_train)
model_selected = lgb.train(params, train_data_selected, num_boost_round=3)

# 评估模型性能
y_pred = model_selected.predict(X_test_selected)


from sklearn.metrics import roc_auc_score

# 计算AUC
auc = roc_auc_score(y_test, y_pred)
print(f"AUC: {auc:.4f}")

AUC: 0.9669



# 示例二代码  效果好的
selected_features.sort()
selected_features

array(['area error', 'mean compactness', 'mean concave points',
  'mean concavity', 'mean radius', 'mean texture',
  'worst concave points', 'worst perimeter', 'worst radius',
  'worst texture'], dtype=object)

# 示例一代码  效果差的
top_features.sort()
top_features

  ['area error',
  'fractal dimension error',
  'mean concave points',
  'mean concavity',
  'mean radius',
  'mean texture',
  'worst concave points',
  'worst perimeter',
  'worst radius',
  'worst texture']

两种训练方式,参数都是随机给,示例二的训练方式,也就是前面着重举例的方式,效果更好一些;
实际分析二者选择的top10重要列,选择出来的列的确也是不同的



特征重要性是模型自带的方法


# 下面是lightgbm算法获取特征重要性的方法
importance = model.feature_importance()

其他算法模型,比如决策树也有这个概念,但却是一个属性,而不是方法
即不同的算法模型,获取特征重要性的API可能不同

特征重要性是一个 数值列表


importance
array([5, 3, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 4,
       3, 1, 0, 0, 0, 3, 0, 0], dtype=int32)

numpy数组,整数

按索引对应列


实际上特征重要性是特征列的重要性,它与输入模型的特征列 按索引顺序一一对应的

解读
- 第1列的重要性为 5
- 第2列的重要性为 3
...
- 第8列的重要性为 4
...



CatBoost

catboost中的cat指categorical,擅长处理分类特征

CatBoost(Categorical Boosting)是一个用于处理分类特征的梯度提升决策树(GBDT)算法。

它由Yandex开发,能够自动处理类别特征,
并通过特定的技术提高预测性能,
尤其是在小数据集上。

1. **处理类别特征**:CatBoost不需要对类别特征进行独热编码(One-Hot Encoding),而是通过使用目标编码和其他技术处理这些特征,这样可以有效减少维度并避免过拟合。

2. **对抗过拟合**:CatBoost使用一种称为“Ordered Boosting”的方法来减少过拟合,确保模型对未见数据具有更好的泛化能力。

3. **高效的训练过程**:CatBoost可以有效地利用多核处理和GPU加速,提高模型训练速度。

自动处理类别特征:
CatBoost 能够自动将类别特征转换为数值特征,
而无需手动进行独热编码(One-Hot Encoding)或标签编码(Label Encoding)。

顺序依赖:
CatBoost 通过引入一种称为“Ordered Boosting”的方法来处理训练数据中的顺序依赖问题,
从而减少了过拟合的风险。

内置处理缺失值:
CatBoost 可以处理包含缺失值的数据,而无需事先进行填充。





import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from catboost import CatBoostClassifier, Pool

# 生成示例数据
np.random.seed(42)
data_size = 1000

# 数值特征
X_num = np.random.rand(data_size, 5)

# 类别特征
X_cat = np.random.randint(0, 10, size=(data_size, 3))

# 标签
y = np.random.randint(0, 2, size=data_size)

# 将数据组合在一起
X = np.hstack([X_num, X_cat])
feature_names = [f'num_{i}' for i in range(X_num.shape[1])] + [f'cat_{i}' for i in range(X_cat.shape[1])]
df = pd.DataFrame(X, columns=feature_names)
df['target'] = y

# 将类别特征标记为类别类型
# for col in [col for col in df.columns if 'cat_' in col]:
#     df[col] = df[col].astype('category')

# 将类别特征标记为类别类型
for col in [col for col in df.columns if 'cat_' in col]:
    df[col] = df[col].astype('string')

data = df.drop('target', axis=1)
label=df['target']

# 划分训练集和测试集
train_pool = Pool(data=data, label=label, cat_features=[col for i, col in enumerate(df.columns) if 'cat_' in col])

test_size = 0.2
X_train, X_test, y_train, y_test = train_test_split(data, label, test_size=test_size, random_state=42)


# 初始化 CatBoost 分类器
model = CatBoostClassifier(iterations=100,
                            learning_rate=0.05,
                            depth=3,
                            loss_function='Logloss',
                            verbose=False)

# 训练模型
model.fit(X_train, y_train, cat_features=[i for i, col in enumerate(X_train.columns) if 'cat_' in col], eval_set=(X_test, y_test), early_stopping_rounds=50)

# 预测
y_pred = model.predict(X_test)
y_pred_proba = model.predict_proba(X_test)[:, 1]

# 评估
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.4f}')


# 如果你想使用 Pool 对象进行预测和评估
test_pool = Pool(data=X_test, label=y_test, cat_features=[col for i, col in enumerate(X_test.columns) if 'cat_' in col])
predictions = model.predict(test_pool)
eval_metrics = model.eval_metrics(test_pool, ['Accuracy'])
print(f'Evaluation Metrics: {eval_metrics}')

X_test.shape
(200, 8)



import pandas as pd
from catboost import CatBoostRegressor, Pool
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 创建示例数据集
data = {
    'gender': ['male', 'female', 'female', 'male', 'male'],
    'age': [23, 30, 22, 45, 39],
    'income': [50000, 60000, 52000, 58000, 62000],
    'target': [200, 250, 210, 300, 320]
}

df = pd.DataFrame(data)

# 定义特征和目标变量
X = df.drop('target', axis=1)
y = df['target']

# 将类别特征指定为字符串类型
X['gender'] = X['gender'].astype(str)

# 切分训练和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 定义类别特征
cat_features = ['gender']

# 创建CatBoost回归模型
model = CatBoostRegressor(cat_features=cat_features, iterations=1000, depth=10, learning_rate=0.1, verbose=0)

# 训练模型
model.fit(X_train, y_train)

# 进行预测
y_pred = model.predict(X_test)

# 评估模型
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse:.2f}')

代码说明

数据准备:通过一个简单的示例数据集,创建包含类别特征(如性别)、数值特征(如年龄、收入)以及目标变量(如target)的数据框。

特征和目标变量的定义:从数据框中分离特征和目标变量,并指定类别特征的类型。

数据切分:使用train_test_split将数据分为训练集和测试集。

模型创建和训练:创建CatBoostRegressor模型,设置类别特征、迭代次数、深度和学习率等参数,并进行训练。

预测和评估:使用训练好的模型对测试集进行预测,计算均方误差(MSE)以评估模型性能。

CatBoost还提供了许多不同的参数和特性,可以根据具体需求进行调节





自动处理类别特征:

CatBoost 使用一种称为“目标统计量”(Target Statistics)的方法将类别特征转换为数值特征。

对于每个类别特征,CatBoost 计算目标变量的平均值或其他统计量作为该类别的数值表示。

Ordered Boosting

为了减少过拟合,CatBoost 在每个迭代中改变数据的排列顺序。

通过这种方式,每个树在训练时不会看到当前样本的标签信息,从而减少了信息泄露。

处理缺失值

CatBoost 使用一种称为“缺失值模式”(Missing Values Mode)的方法来处理缺失值。

默认情况下,CatBoost 将缺失值视为一个新的类别,并为其计算目标统计量。










GBDT

机器学习中的GBDT的全称是Gradient Boosting Decision Tree,即梯度提升决策树。

这是一种基于决策树的集成学习方法,通过结合多个弱决策树形成强分类器。

GBDT使用梯度下降的近似方法,以负梯度作为残差来训练回归树。
具体来说,它利用损失函数的负梯度在当前模型的值作为残差的近似值,
进而拟合一棵CART回归树。
通过多轮迭代,每轮迭代产生一个弱分类器,
每个分类器在上一轮分类器的残差基础上进行训练,
最终将所有树的结论累加起来得到最终答案。

GBDT在处理回归问题和分类问题时都表现出色,
其核心优势在于能够自动进行特征组合和选择,并且具有较高的预测精度。

此外,GBDT还具有较好的鲁棒性,对异常值不敏感,
因此在各种机器学习竞赛和工业应用中都有广泛的应用。













XGB

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

# 加载数据集
data = load_breast_cancer()
X = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)


import numpy as np
import xgboost as xgb
from sklearn.metrics import accuracy_score, confusion_matrix

# 初始化XGBoost分类器
model = xgb.XGBClassifier(learning_rate=0.1, n_estimators=100, max_depth=5)

# 训练模型
model.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = model.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

# 输出混淆矩阵
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))

# 获取特征重要性分数并进行排序
feature_importances = model.feature_importances_
sorted_indices = np.argsort(feature_importances)[::-1]
sorted_feature_importances = feature_importances[sorted_indices]

# 输出特征排序结果
print("Feature Importance Ranking:")
for index, importance in zip(sorted_indices, sorted_feature_importances):
    print(f"Feature {index}: {importance}")

Accuracy: 0.956140350877193
Confusion Matrix:
[[40  3]
  [ 2 69]]
Feature Importance Ranking:
Feature 7: 0.27733203768730164
Feature 27: 0.16386204957962036
Feature 22: 0.15764513611793518
Feature 20: 0.07651687413454056
Feature 23: 0.04797479882836342
Feature 0: 0.03309914469718933
Feature 21: 0.0236650500446558
Feature 26: 0.02285892330110073
Feature 3: 0.022856812924146652
Feature 12: 0.021238965913653374
Feature 1: 0.02031129226088524
Feature 16: 0.01656140573322773
Feature 10: 0.012572740204632282
Feature 13: 0.01170310191810131
Feature 6: 0.010898090898990631
Feature 19: 0.00805942714214325
Feature 24: 0.007531865034252405
Feature 15: 0.006923915818333626
Feature 28: 0.006362638436257839
Feature 4: 0.00583757134154439
Feature 18: 0.005773546174168587
Feature 9: 0.005692197009921074
Feature 11: 0.005683179013431072
Feature 17: 0.005587815307080746
Feature 14: 0.004999605938792229
Feature 5: 0.0044188117608428
Feature 29: 0.004409062676131725
Feature 25: 0.004162525292485952
Feature 8: 0.003179623745381832
Feature 2: 0.0022818183060735464

y_pred
array([1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1,
       0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1,
       1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1,
       0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0,
       1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1,
       0, 1, 1, 0])

lightgbm

import lightgbm as lgb

# 初始化LightGBM模型
params = {
    'objective': 'multiclass',  # 多分类问题
    'num_class': 3,             # 类别数
    'metric': 'multi_logloss',   # 评估指标
    'max_depth':4,
    'num_leaves': 4,
    'learning_rate': 0.05,
}

# 创建数据集
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 训练模型
gbm = lgb.train(params,
                train_data,
                num_boost_round=100,  # 迭代次数
                valid_sets=test_data)  # 提前停止的轮数

# 预测
y_pred = gbm.predict(X_test)
# 将预测的概率转换为类别(最大概率的类别)
y_pred_classes = [int(np.argmax(line)) for line in y_pred]

# 评估
accuracy = accuracy_score(y_test, y_pred_classes)
print(f'Accuracy: {accuracy:.4f}')


[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000720 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 4548
[LightGBM] [Info] Number of data points in the train set: 455, number of used features: 30
[LightGBM] [Info] Start training from score -0.990399
[LightGBM] [Info] Start training from score -0.464306
[LightGBM] [Info] Start training from score -34.538776
Accuracy: 0.9737

y_pred

array[[1.96210874e-02, 9.80378913e-01, 2.87040744e-16],
  [9.97726933e-01, 2.27306703e-03, 9.85591611e-17],
  [9.90695659e-01, 9.30434140e-03, 1.98700051e-16],
  [1.30659852e-02, 9.86934015e-01, 2.35017482e-16],
  [1.23567073e-03, 9.98764329e-01, 7.27056097e-17],
  [9.97902886e-01, 2.09711399e-03, 9.46760623e-17],
  [9.97437881e-01, 2.56211865e-03, 1.04623098e-16],
  [7.85057311e-01, 2.14942689e-01, 8.50152917e-16],
  [8.48823383e-01, 1.51176617e-01, 7.41371706e-16],

y_test

array([1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1,
  0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1,
  1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1,
  0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0,
  1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1,
  0, 1, 1, 0])

# 输出混淆矩阵
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred_classes))

Confusion Matrix:
[[41  2]
[ 1 70]]



XGBoost算法原理

XGBoost(Extreme Gradient Boosting)是一种优化的分布式梯度提升决策树算法。

它在Gradient Boosting Machine(GBM)的基础上进行了许多改进,
以提高模型的准确性和运行效率。

XGBoost的核心思想是通过 迭代地训练多个决策树模型,
并将它们的预测结果相加,以得到最终的预测值。
在每次迭代中,都会学习一个新的决策树模型,以最小化之前模型的损失函数。

Extreme 英/ɪkˈstriːm/ 美/ɪkˈstriːm/
n. 极端;极度;极限;完全相反的事物;极端不同的感情(或境况、行为方式等)
adj. 极端的;极度的;严重的;极大的;偏激的;过分的;严厉的;异乎寻常的;远离中心的

记忆 extr- 超过的 + eme

具体来说,XGBoost采用了梯度提升的方法,
其中每一轮迭代都学习一个新的树模型,以减小之前模型的损失函数。

它支持不同类型的损失函数,
例如均方误差(MSE)用于回归问题,对数损失函数(log loss)用于分类问题。

在构建决策树时,
XGBoost使用CART(Classification and Regression Trees)作为基础学习器,
并采用 最大增益分裂策略 来构建树。

此外,XGBoost还引入了正则化项来控制树的复杂性,防止过拟合。



booster:
决定了XGBoost使用的弱学习器类型,
可以是默认的gbtree(CART决策树),还可以是线性弱学习器gblinear以及DART。

n_estimators:
决策树的数量或迭代次数。
它关系到XGBoost模型的复杂度。
n_estimators太小容易欠拟合,太大又容易过拟合。

objective:
定义了要优化的损失函数。

常见的目标函数包括回归、二分类、多分类等

learning_rate:
学习率控制每棵树的权重调整幅度。

较小的学习率可以使模型更加稳定,但需要更多的迭代次数来收敛。

max_depth:
决策树的最大深度。

增加该值会使模型更复杂,有更高的拟合能力,但也容易过拟合。

min_child_weight:
最小的子节点权重阈值。

如果某个树节点的权重小于这个阈值,则不会再分裂子树。

gamma:
剪枝参数,指定了节点分裂所需的最小损失函数下降值。

较大的值可以限制树的生长,防止过拟合。

subsample:
用于训练每棵树的样本比例。

较小的值可以减少过拟合的风险。

colsample_bytree:
用于训练每棵树时选择特征的比例。

较小的值可以减少过拟合的风险。

reg_alpha和reg_lambda:
分别是L1和L2正则化的惩罚系数,用于控制模型的复杂性。



import xgboost as xgb
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 = data.data
y = data.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 设置XGBoost参数
params = {
    'booster': 'gbtree',
    'objective': 'binary:logistic',
    'learning_rate': 0.1,
    'max_depth': 6,
    'subsample': 0.8,
    'colsample_bytree': 0.8,
    'seed': 42
}

# 训练XGBoost模型
dtrain = xgb.DMatrix(X_train, label=y_train)
dtest = xgb.DMatrix(X_test, label=y_test)
bst = xgb.train(params, dtrain)

# 对测试集进行预测
y_pred_prob = bst.predict(dtest)
y_pred = [1 if prob > 0.5 else 0 for prob in y_pred_prob]

# 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

Accuracy: 0.96







XGB参数

XGB算法中的booster有三种选项:gbtree、gblinear和dart,下面将分别介绍这三种算法的原理及使用场景。

gbtree

原理:

gbtree是XGBoost算法中默认的booster类型,
它基于梯度提升决策树(Gradient Boosting Decision Tree,GBDT)进行实现。

在gbtree中,
每一棵树都是基于前一棵树的残差进行训练的,通过不断迭代来逼近目标函数的最优解。

它使用CART(Classification and Regression Trees)回归树作为基模型,
通过集成多个弱分类器(即多棵回归树)来形成一个强分类器。


使用场景:

gbtree适用于大多数回归和分类问题,特别是当数据具有复杂的非线性关系时。

它能够处理高维数据,并且对于缺失值和异常值具有一定的鲁棒性。

gblinear

原理:

gblinear是基于线性模型的booster,它使用线性回归作为基模型。

在gblinear中,每一轮迭代都会更新模型的权重,以最小化目标函数。

与gbtree不同,gblinear的模型是线性的,
因此它的计算速度通常更快,但可能无法捕捉到数据中的非线性关系。

使用场景:

gblinear适用于 线性可分 或 近似线性可分 的数据集。

当数据维度较高但模型复杂度较低时,gblinear可能是一个更好的选择。

它也适用于需要快速训练和预测的场景。

dart

原理:

dart(Dropouts meet Multiple Additive Regression Trees)
是一种将深度学习的dropout技术引入梯度提升树模型的方法。

在dart中,每一轮迭代都会随机丢弃一部分树,以防止模型过拟合。

通过引入随机性,dart能够增加模型的泛化能力,并在某些情况下获得比gbtree更好的性能。

使用场景:

dart适用于需要防止过拟合的场景,特别是当数据集较小或模型复杂度较高时。

它也适用于需要提高模型泛化能力的场景。

需要注意的是,由于dart引入了随机性,因此训练过程可能比gbtree更慢。

综上所述,gbtree、gblinear和dart各有其独特的原理和使用场景。
在实际应用中,应根据数据集的特点、模型复杂度和训练时间等因素来选择合适的booster类型。



n_estimators(或num_round):

每训练一次,就构建一棵树,通过残差的方式进行一次微调

类型:整数。
含义:梯度提升树的数量,即要构建的树的总数。
影响:
树的数量越多,模型的学习能力越强,但也可能导致过拟合。
需要根据数据集的大小和复杂度进行调整。





max_depth:
所构建的树中最大深度k,可参考 特征数=2^k - 1
但要知道,并不是构建一棵树,是多棵,
所以max_depth的取值比k要小一些,比如小3点,2^6=64,
此时max_depth=3就够用,此部分仅个猜测...

类型:整数。
含义:树的最大深度,即树中节点的最大深度。
影响:限制树的深度可以防止模型过于复杂,有助于防止过拟合。
但过小的深度可能导致模型学习能力不足。







参考

    sklearn2pmml

    人工智能基础部分18-条件随机场CRF模型的应用