- 文档
- 教程
【免费下载链接】Python-100-Days
Python - 100天从新手到大师
本文是《Python-100-Days》系列第 87 天的核心内容,系统讲解集成学习(Ensemble Learning)的三大技术路线——Bagging、Boosting 与 Stacking,并深入剖析 AdaBoost、GBDT、XGBoost、LightGBM 四种主流 Boosting 算法的数学原理、核心超参数与基于 scikit-learn 和原生框架的鸢尾花分类实战代码。读完本文,你将掌握集成学习为什么比单模型更强、Boosting 家族算法的迭代机制差异,以及如何为实际任务配置n_estimators、learning_rate、subsample、eta、num_leaves等关键参数并预防过拟合。
为什么需要集成学习
之前的章节中,我们介绍的大多是机器学习中的单模型,例如第 83 天讲解的决策树和随机森林。事实上,将多个单模型组合成一个综合模型的方式早已成为现代机器学习模型采用的主流方法,这种方法被称为集成学习(ensemble learning)。
集成学习的目标是通过多个弱学习器的组合来构建强学习器。所谓弱学习器,是指分类效果略优于随机猜测的模型——如果单个模型太强,反而容易导致过拟合。通过组合多个弱学习器,可以克服单一模型可能存在的局限性,获得比单一模型更好的泛化能力,因此集成学习通常用于需要高精度预测的场景。
从原理上看,集成学习通过结合多个模型来同时减少模型的偏差和方差:由于集成了多个基础模型,它能够有效降低单一模型可能存在的过拟合问题,也能够处理异常数据和噪声数据,比单一模型更加稳定。当然,集成学习也存在计算开销大、模型可解释性差、超参数调优复杂等代价,这些问题我们会在后文中结合具体算法展开讨论。
集成学习算法分类
集成学习算法主要分为以下三类:
Bagging:并行抽样、投票集成
Bagging(Bootstrap Aggregating)通过从训练数据中随机抽样生成多个数据子集(自助采样,有放回抽样),在这些子集上训练多个模型,并将它们的结果进行结合——分类任务用投票(多数表决),回归任务用求均值。
最典型的 Bagging 算法就是决策树和随机森林章节中讲过的随机森林:从原始训练集中有放回地抽取多个子集,每棵决策树训练时只随机选择一部分特征用于分裂,从而增加树与树之间的多样性、降低相关性,最后通过投票或平均得到集成结果。这种"多个模型并行、结果结合"的结构,是 Bagging 区别于 Boosting 的核心特征。
Boosting:串行迭代、加权纠错
Boosting通过迭代训练多个模型,在每一轮训练时重点关注前一轮预测错误的样本。每个新模型的训练目标是弥补前一轮模型的不足,其基本原理是:
- 初始时对所有样本赋予相同的权重;
- 训练第一个模型后,错误分类的样本权重会增加;
- 训练下一个模型时,重点关注之前模型错误分类的样本;
- 最终将所有模型的结果加权组合(表现好的模型获得更高权重),得到最终输出。
简单的说,Boosting 就是串行地训练一系列弱分类器,使得被先前弱分类器分类错误的样本在后续得到更多关注,最后将这些分类器组合成最优强分类器的过程。经典的 Boosting 算法有 AdaBoost、Gradient Boosting(GBDT)和 XGBoost,也是本文后续几节的主角。
Stacking:模型预测当特征、二级模型做决策
Stacking(堆叠)的思路与前两者都不同:先训练多个模型,将它们的预测结果作为新特征输入到另一个模型(通常称为"二级模型"或"元学习器"Meta Learner)中,由"二级模型"来做最终的预测。原始数据同时输入给全部并行的基学习器,各基学习器生成的预测结果汇总后作为新特征,交给元学习器输出最终预测。这种"先并行训练、再二次学习"的层级结构,让 Stacking 能够学习到多个基模型预测之间的内在关系。
AdaBoost:自适应提升算法
AdaBoost(Adaptive Boosting,自适应提升算法)由 Yoav Freund 和 Robert Schapire 于 1996 年提出,是一种经典的集成学习算法。AdaBoost 的做法非常朴素,体现在两个方面:
- 提高前一轮被弱分类器分类错误的样本的权重;
- 对多个弱分类器进行线性组合时,提高分类效果好的弱分类器的权重。
它的"自适应"体现在会根据前一轮模型的错误动态调整样本的权重。
训练过程的六个关键步骤
AdaBoost 的训练过程是逐步迭代的,关键步骤如下:
第 1 步:初始化样本权重。给每个训练样本分配一个相等的初始权重。对于 $N$ 个样本,初始权重为:
$$ w_{i}^{(1)} = \frac{1}{N}, \ i = 1, 2, \cdots, N $$
这里 $w_{i}^{(1)}$ 表示第 $i$ 个样本的权重,初始时所有样本权重相等。
第 2 步:训练弱学习器。在每一轮迭代中,AdaBoost 根据当前样本权重训练一个弱分类器(例如决策树桩,即深度为 1 的决策树),目标是最小化加权误差。对于第 $t$ 轮训练得到的弱学习器 $h_t$,其加权误差为:
$$ \varepsilon_{t} = \sum_{i=1}^{N} w_{i}^{(t)} \cdot I(y_{i} \neq h_{t}(x_{i})) $$
其中 $y_{i}$ 是第 $i$ 个样本的真实标签,$h_{t}(x_{i})$ 是第 $t$ 轮模型对样本 $x_{i}$ 的预测结果(取值为 1 或 -1),$I(y_{i} \neq h_{t}(x_{i}))$ 是指示函数——样本被错误分类时取 1,否则取 0。
第 3 步:更新分类器权重。计算第 $t$ 轮分类器模型的权重 $\alpha_{t}$:
$$ \alpha_{t} = \frac{1}{2} \ln \left( \frac{1 - \varepsilon_{t}}{\varepsilon_{t}} \right) $$
当分类器的误差较低时,$\alpha_{t}$ 的值较大,说明该分类器在最终投票中的话语权更大。
第 4 步:更新样本权重。根据当前分类器的表现更新样本权重——误分类样本的权重增加,正确分类样本的权重减少:
$$ w_{i}^{(t + 1)} = w_{i}^{(t)} \cdot e^{-\alpha_{t} y_{i} h_{t}(x_{i})} $$
第 5 步:归一化权重。对所有样本的权重进行归一化,使得所有样本的权重和为 1。
第 6 步:组合最终分类器。AdaBoost 的最终分类器是所有弱学习器的加权组合,预测时通过加权投票来决定最终类别:
$$ H(x) = \text{sign} \left( \sum_{t=1}^{T} \alpha_{t} h_{t}(x) \right) $$
其中 $\text{sign}$ 是符号函数,定义如下:
$$ \text{sign}(z) = \begin{cases} +1 \ (z \ge 0) \ -1 \ (z \lt 0) \end{cases} $$
直观算例:假设有 3 个弱学习器 $h_{1}(x)$、$h_{2}(x)$、$h_{3}(x)$,它们的输出分别是+1、-1和+1,对应的权重是 $\alpha_{1} = 0.5$、$\alpha_{2} = 0.3$、$\alpha_{3} = 0.2$,那么加权和为:
$$ \sum_{t=1}^{3} \alpha_{t} h_{t}(x) = 0.5 \times 1 + 0.3 \times (-1) + 0.2 \times 1 = 0.4 $$
由于加权和0.4为正,符号函数输出+1,表示最终预测类别为正类。
基于 scikit-learn 的 AdaBoost 实战
我们以鸢尾花数据集为例,应用 AdaBoost 构建分类模型,完整代码如下:
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import AdaBoostClassifier from sklearn.metrics import classification_report # 数据集的加载和划分 iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=3) # 初始化弱分类器(决策树桩) base_estimator = DecisionTreeClassifier(max_depth=1) # 初始化 AdaBoost 分类器 model = AdaBoostClassifier(base_estimator, n_estimators=50) # 训练模型 model.fit(X_train, y_train) # 预测结果 y_pred = model.predict(X_test) # 输出评估报告 print(classification_report(y_test, y_pred))输出:
precision recall f1-score support 0 1.00 1.00 1.00 10 1 0.90 0.90 0.90 10 2 0.90 0.90 0.90 10 accuracy 0.93 30 macro avg 0.93 0.93 0.93 30 weighted avg 0.93 0.93 0.93 30AdaBoost 关键超参数
使用AdaBoostClassifier时需要注意以下几个超参数的设置:
| 超参数 | 默认值 | 作用与说明 |
|---|---|---|
n_estimators | 50 | 指定要训练的基学习器(弱分类器)的数量 |
learning_rate | 1.0 | 控制每个基学习器在最终模型中的贡献大小,即学习率 |
algorithm | 'SAMME.R' | 决定训练算法:'SAMME'用于多类分类问题,采用加法模型;'SAMME.R'基于 Real AdaBoost,用于加权的二分类和多分类问题,使用加权的重新采样策略 |
base_estimator | None | 基学习器。默认值None表示使用max_depth=1的DecisionTreeClassifier(即决策树桩)。所以上面代码中创建AdaBoostClassifier对象的两个参数都可以省略,因为它们刚好都是默认值 |
调参经验:增大n_estimators可以提高模型的性能,但可能会导致过拟合;增大learning_rate可以加速训练,但可能会导致模型不稳定。通常需要通过交叉验证来找到最佳的n_estimators和learning_rate组合。对于大多数问题,DecisionTreeClassifier(max_depth=1)是常见的选择;如果数据较为复杂,可以考虑其他基学习器,如SVC、LogisticRegression等。
GBDT:梯度提升决策树
GBDT(Gradient Boosting Decision Trees)也是一种强大的集成学习算法,相较于 AdaBoost,GBDT 系列模型应用得更加广泛。GBDT 基于梯度提升(Gradient Boosting)的思想,结合了决策树的优势,通过一系列弱分类器(决策树)逐步改进模型——每次训练时通过**减少前一个模型的误差(拟合残差)**来提高预测性能。
GBDT 使用梯度下降的方式来最小化损失函数:对于回归任务,损失函数通常是均方误差(MSE);对于分类任务,常用的损失函数是对数损失(Log Loss)。下面以二分类任务为例讲解算法原理。
GBDT 的数学原理
1. 损失函数。分类任务中通常使用对数似然损失,对于二分类问题,损失函数如下:
$$ L(y, F(x)) = -y\log(p(x)) - (1 - y)\log(1 - p(x)) $$
其中 $y$ 是实际标签($y \in {0, 1}$,表示类别 0 或 1),$p(x)$ 是模型预测样本 $x$ 属于类别 1 的概率。由于 GBDT 基于梯度提升算法,每一轮更新中都会用梯度下降法来优化这个损失函数。
2. 梯度计算。令当前模型的输出为 $F(x)$,根据对数损失函数,$p(x)$ 通过模型输出 $F(x)$ 转换得到,通常使用 Sigmoid 函数:
$$ p(x) = \frac{1}{1 + e^{-F(x)}} $$
计算损失函数对 $F(x)$ 的梯度,得到:
$$ \frac{\partial{L(y, F(x))}}{\partial{F(x)}} = p(x) - y $$
即梯度为 $p(x) - y$,它告诉我们当前模型的预测 $F(x)$ 与真实标签 $y$ 之间的差距。
3. 模型更新。每一轮的更新包括两步:
- 计算残差:在每一轮迭代中,计算当前模型的残差 $\delta_i = p(x_i) - y_i$,表示每个样本的误差;
- 拟合残差:使用新的基学习器(通常是决策树)来拟合这些残差——在分类任务中,决策树拟合的不是真实标签,而是当前模型的预测误差。
更新规则为:
$$ F_{m + 1}(x) = F_{m}(x) + \eta h_{m}(x) $$
其中 $F_{m}(x)$ 是第 $m$ 轮模型的输出;$h_{m}(x)$ 是第 $m$ 轮训练出的弱学习器(通常是决策树),它预测当前模型的残差;$\eta$ 是学习率,控制每棵树的贡献大小。通过逐步拟合残差,最终生成的 $F(x)$ 就是一个由多棵决策树组成的强学习器。
多分类扩展:多分类任务需要将损失函数和梯度计算做相应扩展,常用的多分类损失函数是多项式对数损失,对每个类别 $k$:
$$ L(y, F(x)) = -\sum_{k=1}^{K} y_{k} \log(p_{k}(x)) $$
其中 $K$ 是类别总数,$y_{k}$ 是目标类别 $k$ 的指示函数,$p_k(x)$ 是样本 $x$ 属于类别 $k$ 的预测概率。
基于 scikit-learn 的 GBDT 实战
同样以鸢尾花数据集为例,使用GradientBoostingClassifier构建分类模型:
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.ensemble import GradientBoostingClassifier from sklearn.metrics import classification_report # 数据集的加载和划分 iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=3) # 初始化 GBDT 分类器 model = GradientBoostingClassifier(n_estimators=32) # 训练模型 model.fit(X_train, y_train) # 预测结果 y_pred = model.predict(X_test) # 输出评估报告 print(classification_report(y_test, y_pred))输出:
precision recall f1-score support 0 1.00 1.00 1.00 10 1 1.00 1.00 1.00 10 2 1.00 1.00 1.00 10 accuracy 1.00 30 macro avg 1.00 1.00 1.00 30 weighted avg 1.00 1.00 1.00 30说明:同一份鸢尾花数据、同样的
random_state=3划分下,GBDT 在本例中取得了比 AdaBoost 更好的测试集表现,这直观地体现了不同集成策略的差异;实际效果会随数据与超参数变化,不能据此得出普适结论。
GBDT 关键超参数
GradientBoostingClassifier中几个重要的超参数:
| 超参数 | 默认值 | 作用与说明 |
|---|---|---|
loss | 'deviance' | 分类任务的损失函数。'deviance'表示对数损失函数;'exponential'表示指数损失函数(即 AdaBoost 的损失函数) |
learning_rate | 0.1 | 控制每棵树对最终预测结果的影响程度。较小的学习率通常带来更好的泛化能力,但需要更多弱分类器(更多树)来拟合训练数据;设置太大则可能导致欠拟合 |
n_estimators | 100 | 指定要训练的基学习器(通常是决策树)的数量 |
subsample | 1.0 | 控制每棵树训练时使用的数据比例。设置小于 1 的值,可在训练每棵树时随机选择部分样本,增加随机性、减少过拟合。通常 0.8 或 0.9 是不错的选择 |
criterion | 'friedman_mse' | 控制分裂时的分裂标准:'friedman_mse'是基于均方误差(MSE)的改进版本,减小对不平衡数据的敏感性,实际任务中通常优于传统 MSE;'mse'是传统均方误差,MSE 越小说明当前节点分裂越好;'mae'是平均绝对误差,对异常值不那么敏感,但实际应用较少 |
validation_fraction | 0.1 | 指定训练过程中的验证集比例,用于执行早期停止(early stopping),避免过拟合。可与n_iter_no_change配合使用,当验证集连续若干轮没有改进时提前停止训练 |
除了上述超参数外,还有一些与决策树类似的超参数(如max_depth、min_samples_split等),此处不再赘述。
调参经验:增加n_estimators(树的数量)时,通常需要减小learning_rate以防过拟合;调整决策树的max_depth和min_samples_split可以减小树的复杂度来防止过拟合;用好subsample和早期停止参数也可以达成类似效果。建议通过网格搜索交叉验证(参考决策树章节中GridSearchCV的用法),结合模型的训练误差和验证误差来寻找最佳参数组合。
XGBoost:可扩展的梯度提升系统
从算法精度、速度和泛化能力等性能指标来看,GBDT 仍然有较大的优化空间。XGBoost(eXtreme Gradient Boosting)正是一种基于 GBDT 的顶级梯度提升模型,由陈天奇在论文《XGBoost: A Scalable Tree Boosting System》中提出。相较于 GBDT:
- 算法精度:XGBoost 将损失函数展开到二阶导数(同时利用一阶和二阶梯度信息),使梯度提升树模型更能逼近其真实损失;
- 算法速度:XGBoost 使用了加权分位数 sketch和稀疏感知算法两个技巧,通过缓存优化和模型并行来提高训练速度;
- 算法泛化能力:通过对损失函数加入正则化项、在加性模型中设置缩减率(收缩)和列抽样等方法,防止模型过拟合。
因为上述原因,XGBoost 不论在学术界、工业界和竞赛圈都很受欢迎,应用广泛。关于 XGBoost 的更多细节,有兴趣的读者可以阅读原始论文,此处不展开介绍。
安装与使用
首先安装依赖项:
pip install xgboost下面展示如何在鸢尾花数据集上使用 XGBoost:
import matplotlib.pyplot as plt import xgboost as xgb from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 数据集的加载和划分 iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=3) # 将数据处理成数据集格式DMatrix格式 dm_train = xgb.DMatrix(X_train, y_train) dm_test = xgb.DMatrix(X_test) # 设置模型参数 params = { 'booster': 'gbtree', # 用于训练的基学习器类型 'objective': 'multi:softmax', # 指定模型的损失函数 'num_class': 3, # 类别的数量 'gamma': 0.1, # 控制每次分裂的最小损失函数减少量 'max_depth': 6, # 决策树最大深度 'lambda': 2, # L2正则化权重 'subsample': 0.8, # 控制每棵树训练时随机选取的样本比例 'colsample_bytree': 0.8, # 用于控制每棵树或每个节点的特征选择比例 'eta': 0.001, # 学习率 'seed': 10, # 设置随机数生成器的种子 'nthread': 16, # 指定了训练时并行使用的线程数 } # 训练模型 model = xgb.train(params, dm_train, num_boost_round=200) # 预测结果 y_pred = model.predict(dm_test) # 输出模型评估报告 print(classification_report(y_test, y_pred)) # 绘制特征重要性评分 xgb.plot_importance(model) plt.grid(False) plt.show()输出的特征重要性评分如下图所示(横轴为 F score,纵轴为特征;条形越长表示该特征对模型越重要):
XGBoost 模型参数详解
先看上面代码中params字典里的几个需要详细说明的参数:
| 参数 | 默认值 | 作用与说明 |
|---|---|---|
booster | 'gbtree' | 基学习器类型。'gbtree'是传统决策树,适用于大多数问题,尤其涉及非线性关系;'gblinear'表示使用线性回归或逻辑回归,适合数据集较小或线性关系较强的场景;'dart'也是基于决策树的模型,但具有丢弃树的机制,可降低过拟合风险,适用于复杂数据集尤其是出现过拟合时 |
objective | 'reg:squarederror' | 指定损失函数(优化目标)。常见选项:'reg:squarederror'(回归任务的 MSE)、'reg:logistic'(回归中的逻辑回归,用于二分类)、'binary:logistic'(二分类逻辑回归,输出概率值)、'binary:logitraw'(二分类逻辑回归,输出未经过 Sigmoid 处理的原始值)、'multi:softmax'(多分类,输出每个类别的最大概率)、'multi:softprob'(多分类,输出每个类别的概率分布) |
eta/learning_rate | 0.3 | XGBoost 中的学习率,推荐将初始值设置为 0.01 到 0.1 |
alpha/lambda | 0 / 1 | 前者控制 L1 正则化项(Lasso)的强度,默认为0;后者控制 L2 正则化项(Ridge)的强度,默认为1 |
scale_pos_weight | 1 | 用于处理类别不平衡问题(尤其是二分类)。在类别严重不平衡时,通过加大少数类权重让模型更关注少数类样本 |
gamma | 0 | 控制每次分裂的最小损失函数减少量,控制树的生长。越大的gamma使树更小、减小过拟合风险;默认值 0 意味着模型不受分裂限制,树会尽可能深,直到节点中没有足够的样本 |
num_class | — | 多分类任务的类别数量;二分类任务无需设置 |
colsample_bytree/colsample_bylevel/colsample_bynode | 1.0 / 1.0 / 1.0 | 分别控制每棵树、每一层、每个节点上采样特征的比例,用于控制模型复杂度。较小的值增加随机性、防止过拟合;较大的值意味着每棵树使用更多特征,可能导致过拟合 |
XGBoosttrain函数参数详解
除了params字典提供的模型参数外,train函数还有几个参数同样值得注意,它们也是模型的超参数:
num_boost_round:树的训练轮数。设置较小的learning_rate并增加训练轮数可以提高模型的稳定性。early_stopping_rounds:实现早期停止机制。当指定轮次的训练中验证集上的损失函数不再减少时,训练自动停止,避免过拟合。feval:用户自定义的评估函数。评估函数有两个参数——模型预测值(NumPy 的ndarray对象)和训练数据(XGBoost 的DMatrix对象);函数返回二元组(name, value),其中name是评估指标名称,value是指标的值。obj:用户自定义的目标函数,用于计算每一步的梯度和二阶导数,从而指导模型优化过程。evals:用于指定一个或多个验证集,值是包含一个或多个(data, label)元组的列表,数据集需为DMatrix对象。训练过程中 XGBoost 会在每一轮迭代后评估验证集性能,通常用于监控过拟合或调整超参数。eval_results:存储在训练过程中计算的所有评估结果,通常传入一个字典。verbose_eval:控制训练过程中评估结果的输出频率。可以设置为整数(多少轮迭代输出一次),也可以设置为True或False(每轮都输出或不输出)。xgb_model:加载之前训练好的模型,以便从中断点继续训练。可以指定一个xgb_model文件或传入一个Booster对象。callbacks:在训练过程中添加自定义回调函数,可在每一轮迭代时提供额外控制,如自动停止训练、调整学习率。
在真实项目中应用 XGBoost
在第 90 天机器学习实战中,XGBoost 被用于 Kaggle 泰坦尼克号生存预测项目:数据经过特征工程后,同样用xgb.DMatrix封装训练集与验证集,以'binary:logistic'作为目标函数、配合gamma、max_depth、lambda、subsample、colsample_bytree、eta等参数训练,再将预测概率(y_pred > 0.5)转换为类别标签。在该案例中,XGBoost 的分类报告(accuracy 0.88)优于逻辑回归(accuracy 0.81),直观体现了集成模型的实战价值;项目还演示了用joblib.dump/joblib.load序列化模型,并通过 Flask 提供/predict接口完成模型部署,有兴趣的读者可以前往该文档查看完整的端到端流程。
LightGBM:轻量高效的梯度提升框架
LightGBM(Light Gradient Boosting Machine)是微软于 2017 年开源的一款顶级 Boosting 算法框架。虽然本质仍然是 GBDT 算法,但它被设计用于大规模数据集的处理,特别是在需要高效率和低内存消耗的场景下。
就 GBDT 系列算法性能而言,XGBoost 已经非常高效,但并非没有缺陷。LightGBM 是一种针对 XGBoost 缺陷的改进版本,通过四个核心方法让 GBDT 算法系统更轻便、更高效,能够做到又快又准:
- 直方图算法(Histogram):将连续特征分箱,显著降低计算与内存开销;
- 单边梯度抽样(GOSS,Gradient-based One-Side Sampling):在训练过程中保留梯度较大的样本,减少计算量;
- 互斥特征捆绑(EFB,Exclusive Feature Bundling):将一些互斥特征做组合,减少特征空间的维度;
- leaf-wise 生长策略:优先对当前叶子节点进行分裂来扩展树的深度(区别于 XGBoost 的 level-wise 逐层生长)。
当然,在较小的数据集上 LightGBM 的优势并不明显;而且不管是 XGBoost 还是 LightGBM,模型的可解释性都是一个短板,超参数调优的难度也比较大。LightGBM 的更多细节可以参考其官方文档,这里直接通过代码感受它的用法。
安装与使用
首先安装依赖项:
pip install lightgbm仍然使用鸢尾花数据集训练模型:
import lightgbm as lgb import numpy as np from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report # 加载和划分数据集 iris = load_iris() X, y = iris.data, iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.8, random_state=3) # 将数据转化为 LightGBM 的数据格式 train_data = lgb.Dataset(X_train, label=y_train) test_data = lgb.Dataset(X_test, label=y_test, reference=train_data) # 设置模型参数 params = { 'objective': 'multiclass', # 多分类问题 'num_class': 3, # 类别数量 'metric': 'multi_logloss', # 多分类对数损失函数 'boosting_type': 'gbdt', # 使用梯度提升树算法 'num_leaves': 31, # 叶子节点数 'learning_rate': 0.05, # 学习率 'feature_fraction': 0.75, # 每次训练时随机选择特征的比例 'early_stopping_rounds': 10 # 连续多少轮没有性能提升就停止迭代 } # 模型训练 model = lgb.train(params=params, train_set=train_data, num_boost_round=200, valid_sets=[test_data]) # 模型预测 y_pred = model.predict(X_test, num_iteration=model.best_iteration) # 将预测结果处理成标签 y_pred_max = np.argmax(y_pred, axis=1) # 查看模型评估报告 print(classification_report(y_test, y_pred_max))LightGBM 关键超参数
这里简单介绍 LightGBM 的超参数,更多细节可以参考官方文档:
| 参数 | 作用与说明 |
|---|---|
objective | 优化目标函数(损失函数)。'regression'用于回归任务;'binary'用于二分类任务;'multiclass'用于多分类任务;'multiclassova'使用一对多策略的多分类任务;'rank_xendcg'、'lambdarank'用于排名任务 |
metric | 评估模型性能的指标。'l2'、'mean_squared_error'是回归任务中的均方误差;'binary_error'是二分类错误率;'multi_logloss'是多分类对数损失;'auc'是二分类任务中的 AUC;'precision'、'recall'、'f1'分别是精度、召回率、F1 分数 |
boosting_type | 提升类型。'gbdt'是传统梯度提升树;'dart'通过随机丢弃树机制防止过拟合;'goss'通过单边梯度抽样加速训练;'rf'是随机森林 |
num_leaves/max_depth | 决策树的叶子节点数 / 最大深度,控制树的复杂度 |
lambda_l1/lambda_l2 | L1 和 L2 正则化参数,用于控制模型复杂度、防止过拟合 |
max_bin | 用于分割连续特征(数据分箱)的最大箱子数 |
feature_fraction | 每次训练时随机选择特征的比例 |
early_stopping_rounds | 评估指标在连续多少轮迭代中没有改进时,训练提前停止 |
总结与选型建议
集成学习通过结合多个模型来减少模型的偏差和方差,通常能获得比单一模型更好的预测效果;由于集成了多个基础模型,它能有效降低单一模型可能存在的过拟合问题,也能处理异常数据和噪声数据,比单一模型更加稳定。与此同时,集成学习也存在计算开销大、模型可解释性差、超参数调优复杂等问题。
除了 XGBoost 和 LightGBM 之外,还有一个因处理类别特征而闻名的 Boosting 算法CatBoost,三者都是 GBDT 系列算法的佼佼者。虽然目前深度学习大行其道,但以 XGBoost、LightGBM 和 CatBoost 为代表的 Boosting 算法在结构化数据的建模上仍然有着广阔的应用场景,即便是在非结构化数据(文本、语音、图像、视频)的建模上也有用武之地。
结合本文与仓库内容,可以形成如下实战路线:先掌握决策树与随机森林中信息熵、信息增益、基尼指数等基础概念,理解 Bagging 的代表算法;再通过本文理解 Boosting 家族"串行纠错"的本质,用 scikit-learn 快速上手 AdaBoost 与 GBDT;随后在数据规模较大、对速度与精度要求高的场景下切换到 XGBoost 或 LightGBM,并结合第 90 天实战的完整项目流程,把集成模型真正落地到预测与部署环节。
- 文档
- 教程
【免费下载链接】Python-100-Days
Python - 100天从新手到大师
相关推荐
repmgr故障排查实战:从日志分析到集群恢复的完整流程
repmgr故障排查实战:从日志分析到集群恢复的完整流程 repmgr是PostgreSQL的轻量级复制管理工具,能够帮助数据库管理员轻松实现PostgreSQ
Python-100-Days 机器学习实战:K-Means 聚类算法从原理到 scikit-learn 实现
Python 100 Days 机器学习实战:K Means 聚类算法从原理到 scikit learn 实现 聚类(Clustering)是数据挖掘与机器学习
文档教程100-Days-Of-ML-Code:7大核心算法全解析,从入门到实战的机器学习之旅
100 Days Of ML Code:7大核心算法全解析,从入门到实战的机器学习之旅 100 Days Of ML Code中文版是一个面向机器学习初学者的实
示例工程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考