全部文章

集成学习

  什么是集成学习

集成学习通过建⽴⼏个模型来解决单⼀预测问题。它的⼯作原理是⽣成多个分类器/模型,各⾃独⽴地学习和作出预测。这些预测最后结合成组合预测,因此优于任何⼀个单分类的做出预测。

复习:机器学习的两个核⼼任务

  • 任务⼀:主要⽤于解决⽋拟合问题
  • 任务⼆:主要⽤于解决过拟合问题

集成学习中boostingBagging

只要单分类器的表现不太差,集成学习的结果总是要好于单分类器的

 

 

Bagging和随机森林

Bagging集成原理

⽬标:把下⾯的圈和⽅块进⾏分类

实现过程:

1) 采样不同数据集

2)训练分类器

3)平权投票,获取最终结果

4)主要实现过程⼩结

bagging集成优点

Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习方法

经过上⾯⽅式组成的集成学习⽅法:

  1. 均可在原有算法上提⾼约2%左右的泛化正确率
  2. 简单, ⽅便, 通用

随机森林构造过程

在机器学习中,随机森林是⼀个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数⽽定。

随机森林 = Bagging + 决策树

例如, 如果你训练了5个树, 其中有4个树的结果是True, 1个树的结果是False, 那么最终投票结果就是True

随机森林够造过程中的关键步骤(M表示特征数⽬):

1)⼀次随机选出⼀个样本,有放回的抽样,重复N(有可能出现重复的样本)

2) 随机去选出m个特征, m <<M,建⽴决策树

思考

  • 1.为什么要随机抽样训练集?
    • 如果不进⾏随机抽样,每棵树的训练集都⼀样,那么最终训练出的树分类结果也是完全⼀样的
  • 2.为什么要有放回地抽样?
    • 如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“⽚⾯的”(当然这样说可能不对),也就是说每棵树训练出来都是有很⼤的差异的;⽽随机森林最后分类取决于多棵树(弱分类器)的投票表决。

总结

随机森林通过构建​​多个决策树​​并集成它们的结果来提高模型性能:

  • ​随机性来源​​:
    • 行随机性: Bagging (自助采样)
    • 列随机性: 每次分割随机选择特征子集
  • ​关键优势​​:
    • 处理高维数据能力
    • 对噪声和异常值鲁棒
    • 内置特征重要性评估
    • 无需复杂特征缩放

包外估计 (Out-of-Bag Estimate)oob

在随机森林构造过程中,如果进⾏有放回的抽样,我们会发现,总是有⼀部分样本我们选不到

这部分数据,占整体数据的⽐重有多⼤呢?

这部分数据有什么⽤呢?

3.1 包外估计的定义

随机森林的 Bagging 过程,对于每⼀颗训练出的决策树 g t,与数据集 D 有如下关系:

对于星号的部分,即是没有选择到的数据,称之为 Out-of-bag(OOB)数据,当数据⾜够多,对于任意⼀组数据 (x , y )是包外数据的概率为:

由于基分类器是构建在训练样本的⾃助抽样集上的,只有约 63.2% 原样本集出现在中,⽽剩余的 36.8% 的数据作为包外数据可以⽤于基分类器的验证集

经验证,包外估计是对集成分类器泛化误差的⽆偏估计.

在随机森林算法中数据集属性的重要性、分类器集强度和分类器间相关性计算都依赖于袋外数据。

3.2 包外估计的⽤途

  • 当基学习器是决策树时,可使⽤包外样本来辅助剪枝 ,或⽤于估计决策树中各结点的后验概率以辅助对零训练样本结点的处理;(参见下文“oob_score的使用”)
  • 当基学习器是神经⽹络时,可使⽤包外样本来辅助早期停⽌以减⼩过拟合 。

随机森林api介绍

sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True,random_state=None, min_samples_split=2)

关键参数详解

1. 树的数量与复杂度

参数 默认值 推荐设置 作用 备注
n_estimators 100 100-500 树的数量,越多越好但有边际效应
  • 边际效应是指在其他条件不变的情况下,如果一种投入要素连续地等量增加,增加到一定产值后,所提供的产品的增量就会下降
max_depth None 5-30 或 None 树的最大深度,None 表示无限扩展  
min_samples_split 2 2-10 节点分裂所需最小样本数
  • 这个值限制了⼦树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进⾏划分,默认是2。
  • 如果样本量不⼤,不需要管这个值。如果样本量数量级⾮常⼤,则推荐增⼤这个值。
min_samples_leaf 1 1-5 叶节点所需最小样本数
  • 这个值限制了叶⼦节点最少的样本数,如果某叶⼦节点数⽬⼩于样本数,则会和兄弟节点⼀起被剪枝,默认是1。
  • 叶是决策树的末端节点。 较⼩的叶⼦使模型更容易捕捉训练数据中的噪声。

2. 随机性与多样性控制

参数 默认值 推荐设置 作用 备注
max_features "auto" "sqrt" 或 0.2-0.8 每棵树考虑的特征比例/数量
  • If "auto", then max_features=sqrt(n_features)#原特征数开方
  • If "sqrt", then max_features=sqrt(n_features)(same as "auto").
  • If "log2", then max_features=log2(n_features)
  • If None, then max_features=n_features
bootstrap True True 是否使用自助采样(放回抽样)  
oob_score False True 是否计算袋外(OOB)分数  

3. 效率优化参数

参数 默认值 推荐设置 作用
n_jobs None -1 使用的CPU核心数 (-1 = 全部核心)
random_state None 固定值 确保结果可复现
verbose 0 1 训练时显示进度信息

4.其他参数

  • Criterion:string,可选( {"gini", "entropy"}, default="gini")
    • 分割特征的测量⽅法
  • min_impurity_decrease: 节点分裂所需的最小不纯度减少值

    • 计算方式​​:父节点不纯度 - 加权平均子节点不纯度
    • ​推荐值​​:0.0(默认)或1e-7至0.1之间(⼀般不推荐改动默认值1e-7。)
    • ​特点​​:
      • 比基于样本数量的停止条件更灵活
      • 对类别不平衡数据更有效
      • 减少不重要分裂,防止过拟合
    • 这个值限制了决策树的增⻓,如果某节点的不纯度(基于基尼系数,均⽅差)⼩于这个阈值,则该节点不再⽣成⼦节点。即为叶⼦节点 。
  • oob_score - 袋外分数评估
    • oob_score : bool, default=False
    • 核心价值:
      • ​零成本验证​​:使用未被包含在训练集中的样本进行验证(约37%)
      • ​模型选择​​:替代交叉验证的高效选择
      • ​过拟合检测​​:比较训练分数和oob分数差距
      • ​特征重要性​​:计算基于oob的permutation importance

上⾯决策树参数中最重要的包括

  • 最⼤特征数max_features
  • 最⼤深度max_depth
  • 内部节点再划分所需最⼩样本数min_samples_split
  • 叶⼦节点最少样本数min_samples_leaf

完整代码示例:

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score

# 创建示例数据集
X, y = make_classification(
    n_samples=1000, 
    n_features=20, 
    n_classes=2, 
    random_state=42
)

# 数据分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 创建并训练随机森林
rf = RandomForestClassifier(
    n_estimators=300,
    max_depth=15,
    min_samples_leaf=3,
    max_features='sqrt',
    bootstrap=True,
    oob_score=True,
    n_jobs=-1,
    random_state=42,
    verbose=1
)

rf.fit(X_train, y_train)

# 模型评估
train_pred = rf.predict(X_train)
test_pred = rf.predict(X_test)

print(f"训练准确率: {accuracy_score(y_train, train_pred):.4f}")
print(f"测试准确率: {accuracy_score(y_test, test_pred):.4f}")
print(f"OOB分数: {rf.oob_score_:.4f}")

# 特征重要性分析
for i, importance in enumerate(rf.feature_importances_):
    print(f"特征 {i}: {importance:.4f}")
查看打印结果
训练准确率: 0.9712
测试准确率: 0.8950
OOB分数: 0.8950
特征 0: 0.0137
特征 1: 0.1052
特征 2: 0.0175
特征 3: 0.0111
特征 4: 0.0119
特征 5: 0.3607
特征 6: 0.0156
特征 7: 0.0123
特征 8: 0.0125
特征 9: 0.0101
特征 10: 0.0148
特征 11: 0.0231
特征 12: 0.0130
特征 13: 0.0128
特征 14: 0.0823
特征 15: 0.0124
特征 16: 0.0154
特征 17: 0.0115
特征 18: 0.2308
特征 19: 0.0135

 

注意

随机森林的建⽴过程

树的深度、树的个数等需要进⾏超参数调优

超参数调优策略

  • 定义超参数的选择列表
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [10, 20, 30, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# 使用 GridSearchCV 或 RandomizedSearchCV 搜索最佳参数
param = {"n_estimators": [120,200,300,500,800,1200], "max_depth": [5, 8, 15, 25, 30]}
  • 使⽤GridSearchCV进⾏⽹格搜索
# 超参数调优
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(x_train, y_train)
print("随机森林预测的准确率为:", gc.score(x_test, y_test))

性能优化技巧

​特征预排序:​

# 启用内部优化,处理连续特征更高效
rf = RandomForestClassifier(ccp_alpha=0.0, min_impurity_decrease=0.0)

内存与速度优化:​

# 减小树的存储空间(在特征很多时特别有效)
rf = RandomForestClassifier(
    memory='./rf_cache/',  # 指定缓存目录
    max_leaf_nodes=1000,    # 限制叶节点数量
    ccp_alpha=0.01          # 复杂度剪枝
)

常见问题解决方案

  1. ​过拟合问题​​:

# 解决方案:降低复杂度
rf = RandomForestClassifier(
    max_depth=10,
    min_samples_leaf=5,
    min_samples_split=10,
    max_features=0.5
)

训练时间过长​​:

# 解决方案:使用子采样或特征选择
rf = RandomForestClassifier(
    max_samples=0.5,   # 使用50%样本
    max_features=0.3,   # 使用30%特征
    n_jobs=-1
)

​类别不平衡处理​​:

# 解决方案:平衡采样策略
rf = RandomForestClassifier(
    class_weight='balanced',
    sampling_strategy='auto'
)

​高方差问题​​:

# 解决方案:增加树的数量和使用稳定参数
rf = RandomForestClassifier(
    n_estimators=500,
    max_depth=15,
    oob_score=True,
    random_state=42
)

小结

bagging集成过程【知道】

  • 1.采样 — 从所有样本⾥⾯,采样⼀部分
  • 2.学习 — 训练弱学习器
  • 3.集成 — 使⽤平权投票

随机森林介绍【知道】

  • 随机森林定义
    • 随机森林 = Bagging + 决策树
  • 流程:
    • 1.随机选取m条数据
    • 2.随机选取k个特征
    • 3.训练决策树
    • 4.重复1-3
    • 5.对上⾯的弱决策树进⾏平权投票
  • 注意:
    • 1.随机选取样本,且是有放回的抽取
    • 2.选取特征的时候,选择m<<M,M是所有的特征数
  • 包外估计
    • 如果进⾏有放回的对数据集抽样,会发现,总是有⼀部分样本选不到;
  • api
    • sklearn.ensemble.RandomForestClassifier()
  • Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习⽅法【了解】
  • bagging的优点【了解】
    • 1.均可在原有算法上提⾼约2%左右的泛化正确率
    • 2.简单, ⽅便, 通⽤

Boosting

1什么是boosting

随着学习的积累从弱到强

简而言之:每新加入一个弱学习器,整体能力就会得到提升

代表算法:Adaboost,GBDT,XGBoost,LightGBM

2 实现过程:

1.训练第⼀个学习器

2.调整数据分布

3.训练第⼆个学习器

4.再次调整数据分布

5.依次训练学习器,调整数据分布

6.整体过程实现

3 bagging集成与boosting集成的区别:

  • 区别⼀:数据⽅⾯
    • Bagging:对数据进⾏采样训练;
    • Boosting:根据前⼀轮学习结果调整数据的重要性。
  • 区别⼆:投票⽅⾯
    • Bagging:所有学习器平权投票;
    • Boosting:对学习器进⾏加权投票。
  • 区别三:学习顺序
    • Bagging的学习是并⾏的,每个学习器没有依赖关系;
    • Boosting学习是串⾏,学习有先后顺序。
  • 区别四:主要作⽤
    • Bagging主要⽤于提⾼泛化性能(解决过拟合,也可以说降低⽅差)
    • Boosting主要⽤于提⾼训练精度 (解决⽋拟合,也可以说降低偏差)

AdaBoost介绍

4.1 构造过程细节

  • 步骤⼀:初始化训练数据权重相等,训练第⼀个学习器。
    • 该假设每个训练样本在基分类器的学习中作⽤相同,这⼀假设可以保证第⼀步能够在原始数据上学习基本分类器H 1(x)
  • 步骤⼆:AdaBoost反复学习基本分类器,在每⼀轮m = 1, 2, ..., M 顺次的执⾏下列操作:
    • (a) 在权值分布为D t 的训练数据上,确定基分类器;
    • (b) 计算该学习器在训练数据中的错误率

    • (c) 计算该学习器的投票权重

    • (d) 根据投票权重,对训练数据重新赋权

    • 将下⼀轮学习器的注意⼒集中在错误数据上

数学原理:

        1. ​αₜ 恒为正数​
          ∵ αₜ = ½ ln[(1-εₜ)/εₜ] 且 εₜ < 0.5 (弱分类器有效性要求)
          ∴ 1-εₜ > εₜ ⇒ (1-εₜ)/εₜ > 1 ⇒ αₜ > 0
          ⇒ e^(αₜ) > 1, e^(-αₜ) < 1

        2. ​权重缩放方向​

          • 预测正确 → 乘以 e^(-αₜ) < 1 → ​​权重减小​
          • 预测错误 → 乘以 e^(αₜ) > 1 → ​​权重增大​
  • 重复执⾏a到d步,m次;
  • 步骤三:对m个学习器进⾏加权投票

 

4.2 关键点剖析

如何确认投票权重?

如何调整数据分布?

4.3 案例:

给定下⾯这张训练数据表所示的数据,假设弱分类器由xv产⽣,其阈值v使该分类器在训练数据集上的分类误差率最低,试⽤Adaboost算法学习⼀个强分类器。

问题解答:

步骤⼀:初始化训练数据权重相等,训练第⼀个学习器:

步骤⼆:AdaBoost反复学习基本分类器,在每⼀轮m = 1, 2, ..., M 顺次的执行下列操作:

m=1的时候:

(a)在权值分布为D1的训练数据上,阈值v取2.5时分类误差率最低,故基本分类器为:

6,7,8被分错

(b)计算该学习器在训练数据中的错误率

(c)计算该学习器的投票权重

(d)根据投票权重,对训练数据重新赋权:

根据下公式,计算各个权重值

经计算得,D2的值为:

D 2 = (0.07143, 0.07143, 0.07143, 0.07143, 0.07143, 0.07143, 0.16667, 0.16667, 0.16667, 0.07143)

计算过程:

分类器H1(x)在训练数据集上有3个误分类点。

m=2的时候:

(a)在权值分布为D2的训练数据上,阈值v取8.5时分类误差率最低,故基本分类器为:

3,4,5被分错

 

(b)计算该学习器在训练数据中的错误率

(c)计算该学习器的投票权重

(d)根据投票权重,对训练数据重新赋权:

经计算得,D 3 的值为:

D 3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.1667, 0.1060, 0.1060, 0.1060, 0.0455)

分类器H2(x)在训练数据集上有3个误分类点。

m=3的时候:

(a)在权值分布为D3的训练数据上,阈值v取5.5时分类误差率最低,故基本分类器为:

(b)计算该学习器在训练数据中的错误率ε3 = 0.1820

(c)计算该学习器的投票权重α3 = 0.7514

(d)根据投票权重,对训练数据重新赋权:

经计算得,D4的值为:

D4 = (0.125, 0.125, 0.125, 0.102, 0.102, 0.102, 0.065, 0.065, 0.065, 0.125)

步骤三:对m个学习器进⾏加权投票,获取最终分类器

分类器H3(x)在训练数据集上的误分类点个数为0。

4.4 api介绍

from sklearn.ensemble import AdaBoostClassifier

api链接:https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.AdaBoostClassifier.html#sklearn.ensemble.AdaBoostClassifier

5 ⼩结

  • AdaBoost构造过程【知道】
  • 步骤⼀:初始化训练数据权重相等,训练第⼀个学习器;
  • 步骤⼆:AdaBoost反复学习基本分类器;
  • 步骤三:对m个学习器进⾏加权投票

GBDT(梯度提升决策树)

GBDT 的全称是 Gradient Boosting Decision Tree,在传统机器学习算法中,GBDT算的上TOP3的算法。

  • Boosting(提升): 属于集成学习的一种策略,通过串行训练多个弱学习器(通常是决策树),每个后续模型都专注于纠正前序模型的错误。

  • Gradient(梯度): 利用损失函数的负梯度方向(下降最快的方向)作为当前模型需要拟合的目标(即“残差”的近似),这是其名称中“梯度”的来源。

  • Decision Tree(决策树): 使用CART(分类与回归树)作为基础的弱学习器。

GBDT 是一种​​集成学习算法​​,通过迭代构建多个决策树来优化模型性能,​​核心思想是利用梯度下降来最小化损失函数​​。

先来个通俗理解:假如有个⼈30岁,我们⾸先⽤20岁去拟合,发现损失有10岁,这时我们⽤6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们⽤3岁拟合剩下的差距,差距就只有⼀岁了。如果我们的迭代轮数还没有完,可以继续迭代下⾯,每⼀轮迭代,拟合的岁数误差都会减⼩。最后将每次拟合的岁数加起来便是模型输出的结果。

算法原理

  1. 初始化:用一个常数(如训练集均值)作为初始预测值,使初始损失函数最小。
  2. 迭代训练
    • 计算当前模型的预测值与真实值的残差(或梯度)。
    • 以残差为目标,训练一棵新的决策树。
    • 将新树的预测结果乘以学习率(步长),累加到总预测值中。
  3. 终止条件:当损失函数不再显著下降、树的数量达到预设值或残差足够小时,停止迭代。

GBDT 基于Boosting框架,通过迭代训练一系列弱学习器(决策树),每棵树学习的是之前所有树预测结果与真实值的残差(或梯度),最终将所有树的预测结果累加得到最终输出。

GBDT VS 传统Boosting​

  • AdaBoost​​:改变样本权重
  • ​GBDT​​:拟合损失函数的负梯度

它在被提出之初就被认为是泛化能力(generalization)较强的算法。近些年更因为被用于搜索排序的机器学习模型而引起大家关注。

GBDT=梯度下降+Boosting+决策树

损失函数与伪残差​

常见损失函数:

任务类型 损失函数 伪残差计算
​回归​

均方误差(MSE)、绝对误差(MAE)、L2损失: ½(y-ŷ)²

y - ŷ
​二分类​ 对数损失: log(1+e^(-yŷ)) y * (1 - sigmoid(ŷ))
​多分类​ Softmax交叉熵 y - softmax(ŷ)

 

数学推导(以回归问题为例)

🎯 ​​1. 损失函数(目标函数)

假设损失函数为均方误差(MSE),那么目标函数为:
  • 核心作用​​:模型优化的目标,衡量预测值  与真实值  的误差
  • ​关键细节​​:
    • :归一化系数
      •  表示平均损失
      •  是为后续求导时消除平方项的系数2
    • ​平方项​​:对预测误差进行放大惩罚,使模型更关注大误差样本
  • ​优化目标​​:找到使  最小的函数 

🔰 ​​2. 模型初始化

用一个简单的常数值c初始化模型(如目标值的平均值):

🔄 ​​3. 第 m 次迭代过程(核心)​

📐 ​​3.1 计算伪残差​


和 ​​本质上是同一个概念​​,都表示 ​​第  次迭代时样本  的残差​​。两者只是下标顺序不同,但含义完全一致。

梯度解释​​:

  • 负梯度方向  是损失函数下降最快的方向
  • 对MSE损失求导:

物理意义​​:

  • 残差 = 当前模型预测的“错误量”
  • 新树将学习修正这些错误

🌳 ​​3.2 训练决策树​

训练决策树拟合残差rmi

⚖️ ​​3.3 更新模型​

  • ​组件解析​​:
    • :前序模型(旧模型)
    • :新训练的残差预测树
    • :学习率(步长)控制每棵树的贡献,防止过拟合(0 <  ≤ 1)。
  • ​学习率作用​​:
    • 控制新树对模型的修正强度
    •  小 → 保守更新 → 需要更多树
    •  大 → 激进更新 → 可能不稳定
    • 其中λ为学习率
  • ​数学意义​​:沿梯度方向更新模型:

🏁 ​​4. 最终模型预测

  • 符号说明​​:
    • :即学习率 
    • :迭代轮次(树的总数量)
  • ​模型本质​​:

📊 ​​完整流程演示(房价预测示例)​

样本 真实值 初始模型 残差 树1预测 更新后预测(λ=0.5)
A 200 180 +20 +22 180+0.5×22=191
B 160 180 -20 -18 180+0.5×(-18)=171
C 190 180 +10 +12 180+0.5×12=186

​迭代效果​​:

  • 平均绝对误差从20万 → 降到9.5万(对比初始模型)

🔑 ​​核心思想总结​

  1. ​残差学习​

    • 每棵树学习前序模型的​​预测残差​
    • 新树输入:特征 
    • 新树目标:残差 
  2. ​梯度下降本质​

模型更新 fm=fm1λL

    • 负梯度  即残差方向
    • 决策树作为函数逼近器计算梯度方向
  1. ​正则化机制​

    • ​学习率 ​:控制单棵树影响
    • ​树数量 ​:限制复杂度
    • ​树深度​​:约束弱学习器表达能力

通过这种「串行构建残差修正器」的机制,GBDT能够逐步降低偏差,同时通过参数控制(λ, M, 树深度)避免过拟合。

示例代码

from sklearn.ensemble import GradientBoostingRegressor
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 加载数据
boston = load_boston()
X, y = boston.data, boston.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 初始化GBDT模型
gbdt = GradientBoostingRegressor(
    n_estimators=100,
    learning_rate=0.1,
    max_depth=3,
    min_samples_split=2,
    random_state=42
)

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

# 预测与评估
y_pred = gbdt.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"MSE: {mse}")

# 查看特征重要性
feature_importance = gbdt.feature_importances_
print("特征重要性排序:", sorted(zip(boston.feature_names, feature_importance), key=lambda x: x[1], reverse=True))
 

参数调优指南​

关键超参数:

参数类型 参数 推荐值 作用
​控制树结构​ max_depth 3-10 树复杂度
  num_leaves 20-120 LightGBM特有
​防止过拟合​ learning_rate 0.01-0.3 步长收缩
  subsample 0.6-0.9 样本采样率
  colsample_bytree 0.6-0.9 特征采样率
​正则化​ reg_alpha 0-0.5 L1正则化
  reg_lambda 0-1 L2正则化
​迭代控制​ n_estimators 100-5000 树的数量
  early_stopping 50-100 早停轮数

调参建议

  1. 基础参数
    • 树的数量(n_estimators):通常 100-1000,结合学习率调整。
    • 学习率(learning_rate):0.01-0.3,小学习率需更多树。
  2. 树结构参数
    • 最大深度(max_depth):3-10,控制模型复杂度。
    • 最小样本分裂数(min_samples_split):避免过拟合。
  3. 正则化参数
    • 子采样率(subsample):0.5-1,类似随机森林的 Bagging。

经典库

  • scikit-learnGradientBoostingRegressor/Classifier

GBDT 作为经典的集成学习算法,其思想启发了 XGBoost、LightGBM 等高效变种,在工业界和学术界仍被广泛应用。理解其原理对掌握现代机器学习模型具有重要意义。 

GBDT变体与发展​

  • XGBoost:极致优化效率与精度,支持并行、分布式计算。(kaggle竞赛神器)

  • LightGBM:微软开发,基于直方图算法,速度快内存低。

  • CatBoost:自动处理类别特征,减少过拟合。

4.1 主要变体对比

算法 创新点 优势
​XGBoost​

增加正则项(γ,λ)控制复杂度;

精确贪婪算法

加权分位数

引入二阶导数信息,加速收敛;

支持并行计算(特征粒度并行)

精确控制过拟合

处理稀疏数据

​LightGBM​

GOSS特征采样

使用直方图算法减少计算量;

基于 Leaf-wise 生长策略,减少树的深度;

支持类别特征直接处理。

训练速度快

内存消耗低

​CatBoost​

对称树结构

Ordered目标编码:引入有序提升(Ordered Boosting)减少偏差。

GPU优化

处理类别特征时减少噪声

处理类别特征

避免梯度偏移

实战应用​

6.1 特征工程技巧

# GBDT特征处理特殊之处
1. 无需标准化:树模型对幅度不敏感
2. 缺失值处理:自动处理为单独分支
3. 类别特征:推荐使用one-hot编码(XGBoost)或标签编码(LightGBM)
4. 特征组合:通过树结构自动创建

# 特征重要性使用
model = LGBMClassifier().fit(X, y)
importances = model.feature_importances_

6.2 LightGBM实际案例代码

# 使用LightGBM进行信用评分建模
import lightgbm as lgb
from sklearn.model_selection import train_test_split

# 数据准备
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)

# 创建Dataset
train_data = lgb.Dataset(X_train, label=y_train, free_raw_data=False)
val_data = lgb.Dataset(X_val, label=y_val, reference=train_data)

# 参数设置
params = {
    'objective': 'binary',
    'metric': ['auc', 'binary_logloss'],
    'num_leaves': 45,
    'learning_rate': 0.08,
    'feature_fraction': 0.75,
    'bagging_fraction': 0.8,
    'reg_alpha': 0.3,
    'reg_lambda': 0.5
}

# 训练模型
model = lgb.train(
    params,
    train_data,
    valid_sets=[val_data],
    num_boost_round=1000,
    early_stopping_rounds=50,
    verbose_eval=20
)

# 解释模型
lgb.plot_importance(model, max_num_features=15)
lgb.plot_tree(model, tree_index=0, figsize=(20, 8))

与随机森林(RF)的区别

特性 GBDT 随机森林 (RF)
训练方式 串行(顺序添加树) 并行(独立训练树)
基学习器目标 拟合残差(错误) 拟合原始标签
结果组合 加权求和 投票/平均
方差 vs 偏差 主要降低偏差 主要降低方差
过拟合风险 较高(需谨慎调参) 较低(天然抗过拟合)
数据敏感性 对噪声较敏感 更鲁棒

 

算法 核心差异 优势场景
随机森林 基于 Bagging,树间独立,通过随机采样降低方差。 大规模数据、并行计算
Adaboost 基于样本权重调整,每棵树关注前序错误样本。 二分类、简单特征场景
GBDT 基于梯度优化,每棵树拟合残差,对异常值更敏感(需预处理)。 高精度回归、复杂特征

 

优点总结

✅ 预测精度高:能有效处理非线性关系,在各类竞赛(如 Kaggle)中表现优异。
✅ 处理混合类型数据(数值+类别)
✅ 模型可解释性较好:通过特征重要性分析,能解释模型决策依据。
✅ 灵活支持自定义损失函数

缺点总结

❌ 训练时间较长(尤其树数量多时):计算复杂度高,迭代训练需串行处理,难以并行(相比随机森林)。

❌ 超参数较多(学习率、树深度、子采样率等需调优):调参复杂:需优化树的数量、深度、学习率等多个超参数。

❌ 对噪声和异常值较敏感:残差计算易受极端值影响,需提前处理。

❌ 串行训练难以完全并行化(但XGBoost/LightGBM优化了此问题)

总结​

GBDT通过梯度提升框架将弱小的决策树组合成强大的模型,成为当前工业界​​表格数据​​建模的首选算法。现代实现如XGBoost、LightGBM和CatBoost在保持高精度的同时大幅优化了速度和内存效率。

未来发展趋势:

  1. 与深度学习的深度融合
  2. 自动机器学习集成
  3. 可解释性增强技术
  4. 高效分布式计算优化

在实际应用中,GBDT通常需要根据数据特性和计算资源选择合适的实现:

  • ​高精度需求​​ → XGBoost
  • ​大规模数据集​​ → LightGBM
  • ​类别特征丰富​​ → CatBoost

关键特点

  • 非线性能力强: 通过树的分裂捕捉复杂模式。

  • 特征组合自动学习: 决策树天然支持特征交叉。

  • 鲁棒性好: 对异常值、缺失值有一定容忍度。

  • 可解释性: 相比神经网络,树模型可通过特征重要性(如分裂增益)提供解释。

  • 无需特征缩放: 对输入数据的量纲不敏感。

正则化防止过拟合

  • 学习率(ν: 缩小每棵树的贡献(通常取0.01~0.1)。

  • 树复杂度控制: 限制树的最大深度、叶子节点数、分裂所需最小样本数等。

  • 子采样(Subsampling): 每次迭代随机选取部分样本或特征训练(类似随机森林)。

  • 早停(Early Stopping): 在验证集性能不再提升时停止迭代。

XGBoost

XGBoost(Extreme Gradient Boosting)全名叫极端梯度提升树,XGBoost是集成学习⽅法的王牌,在Kaggle数据挖掘⽐赛中,⼤部分获胜者⽤了XGBoost。

XGBoost在绝⼤多数的回归和分类问题上表现的⼗分顶尖,本节将较详细的介绍XGBoost的算法原理。

算法原理

1 最优模型的构建⽅法

我们在前⾯已经知道,构建最优模型的⼀般⽅法是最小化训练数据的损失函数

我们⽤字⺟ L表示损失,如下式:

 

其中,F是假设空间

假设空间是在已知属性和属性可能取值的情况下,对所有可能满⾜⽬标的情况的⼀种毫⽆遗漏的假设集合。

 上式称为经验风险最小化,训练得到的模型复杂度较⾼。当训练数据较⼩时,模型很容易出现过拟合问题。

 因此,为了降低模型的复杂度,常采⽤下式:

 上式称为结构风险最小化,结构⻛险最⼩化的模型往往对训练数据以及未知的测试数据都有较好的预测 。 

其中J(f )为模型的复杂度,

 应⽤:

  • 决策树的⽣成和剪枝分别对应了经验⻛险最⼩化和结构⻛险最⼩化;
  • XGBoost的决策树⽣成是结构⻛险最⼩化的结果,后续会详细介绍;

 2 XGBoost的⽬标函数推导

 2.1 ⽬标函数确定

目标函数,即损失函数,通过最⼩化损失函数来构建最优模型。

由前⾯可知, 损失函数应加上表示模型复杂度的正则项,且XGBoost对应的模型包含了多个CART树,因此,模型的⽬标函数(正则化的损失函数)为:

(3.1)

​核心作用​​:通过最小化该函数构建最优集成模型

正则化项是K棵树的正则化项相加⽽来的。

符号 含义
第  个样本的真实值
模型对第  个样本的预测值
第  棵CART树
树的总数量
单棵树的正则化函数

防止模型过拟合的双重控制:

  1. ​纵向控制​​:约束单棵树的复杂度
  2. ​横向控制​​:限制总体树结构

 

 

2.2 CART树的介绍

上图为第K棵CART树,确定⼀棵CART树需要确定两部分;

第⼀部分就是树的结构,这个结构将输⼊样本映射到⼀个确定的叶⼦节点上,记为fk(x);

第⼆部分就是各个叶子节点的值q(x )表示输出的叶⼦节点序号,wq(x )表示对应叶⼦节点序号的值。

由定义得:

(3.2)

符号 含义 作用
输入样本的特征向量 待预测的数据(如用户年龄、收入等)
树模型索引 表示集成模型中第  棵树
​规则映射函数​ 根据特征判断样本应落入哪个叶子节点
​叶子节点权重向量​ 存储每个叶子节点的预测值
权重向量索引 取出样本对应叶子节点的预测值
最终预测值 第  棵树对样本  的输出结果

2.3 树的复杂度定义

2.3.1 定义每课树的复杂度

XGBoost法对应的模型包含了多棵cart树,定义每棵树的复杂度:

(3.4)

其中T为叶⼦节点的个数,||w||为叶⼦节点向量的模 。γ表示节点切分的难度,λ表示L2正则化系数。

符号 名称 数学意义 实际作用
叶子节点数 树的分支总量 ​控制树深度​​:惩罚复杂树结构
叶子权重L2范数 ​平滑预测值​​:防止极端权重
节点切分难度 单节点分裂代价

​剪枝强度​​:γ↑ → 分裂门槛↑

γ 的物理意义​​:
分裂收益阈值,当增益  时停止分裂

L2正则化系数 权重衰减强度 ​抑制过拟合​​:λ↑ → 权重波动↓

2.3.2 树的复杂度举例

设我们要预测⼀家⼈对电⼦游戏的喜好程度,考虑到年轻和年⽼相⽐,年轻更可能喜欢电⼦游戏,以及男性和⼥性相⽐,男性更喜欢电⼦游戏,故先根据年龄⼤⼩区分⼩孩和⼤⼈,然后再通过性别区分开是男是⼥,逐⼀给各⼈在电⼦游戏喜好程度上打分,如下图所示:

就这样,训练出了2棵树tree1和tree2,类似之前gbdt的原理,两棵树的结论累加起来便是最终的结论,所以:

  • ⼩男孩的预测分数就是两棵树中⼩孩所落到的结点的分数相加:2 + 0.9 = 2.9。
  • 爷爷的预测分数同理:-1 + (-0.9)= -1.9。

具体如下图所示:

如下例树的复杂度表示:

2.4 ⽬标函数推导

核心目标:​​
XGBoost在构建第 t 棵树时,需要找到一个​​最好的树结构​​(怎么分枝)和​​最佳的叶子权重​​(叶子节点的预测值),使得模型的​​整体损失最小​​(既要预测准,又要模型简单不过拟合)。目标函数就是用来衡量“好与坏”的标准。

整体推导路线图

根据:

(3.1)

共进⾏t次迭代的学习模型的⽬标函数为:

由前向分布算法可知,前t-1棵树的结构为常数

(3.5)

我们知道,泰勒公式的⼆阶导近似表示:

(3.6)

ft(xi )为Δx, 则(3.5)式的⼆阶近似展开:

 

(3.7)

(3.8)

其中:

 

 

gihi分别表示损失函数关于预测值的一阶导数 (gi) 和二阶导数 (hi) 的定义式 ,用于目标函数的泰勒展开近似。

 表示前t-1棵树组成的学习模型的预测误差。

当前模型往预测误差减⼩的⽅向进⾏迭代。

 

忽略(3.7)式常数项,并结合(3.4)式,得:

(3.9)

通过(3.2)式简化(3.9)式: 

(3.10)

 

(3.10)式第⼀部分是对所有训练样本集进⾏累加,

此时,所有样本都是映射为树的叶⼦节点,

所以,我们换种思维,从叶⼦节点出发,对所有的叶⼦节点进⾏累加,得:

(3.11)

令:

 

Gj表示映射为叶⼦节点 j 的所有输⼊样本的⼀阶导之和,同理,Hj表示⼆阶导之和。

得:

 

(3.12)

 这一步是 XGBoost 推导叶子节点最优权重、计算分裂增益的关键基础 。

对于第 t 棵CART树的某⼀个确定结构(可⽤q(x)表示),其叶⼦节点是相互独⽴的,

GjHj是确定量,因此,(3.12)可以看成是关于叶⼦节点w的⼀元⼆次函数 。

最⼩化(3.12)式,得:

 

(3.13)

 这是 XGBoost 算法中,叶子节点最优权重的计算公式 ,用于确定梯度提升树中每个叶子节点的最佳预测值(权重)。

把(3.13)带⼊到(3.12),得到最终的⽬标函数:

 

(3.14)

 这是 XGBoost 算法中,代入叶子节点最优权重后,目标函数 obj 的最优值计算公式 。

(3.14)也称为打分函数(scoring function),它是衡量树结构好坏的标准,值越⼩,代表这样的结构越好 。

此式用于计算 XGBoost 模型在当前树结构下,目标函数能达到的最小值,是判断树结构分裂增益(如计算分裂前后 obj 差值)、指导树生长的关键依据 。

我们⽤打分函数选择最佳切分点,从⽽构建CART树。

3 XGBoost的回归树构建⽅法

3.1 计算分裂节点

在实际训练过程中,当建⽴第 t 棵树时,XGBoost采⽤贪⼼法进⾏树结点的分裂:

从树深为0时开始:

  • 对树中的每个叶⼦结点尝试进⾏分裂;
  • 每次分裂后,原来的⼀个叶⼦结点继续分裂为左右两个⼦叶⼦结点,原叶⼦结点中的样本集将根据该结点的判断规则分散到左右两个叶⼦结点中;
  • 新分裂⼀个结点后,我们需要检测这次分裂是否会给损失函数带来增益,增益的定义如下:

这是 XGBoost 算法中,树节点分裂增益(Gain)的计算公式推导,用于判断节点分裂是否能优化目标函数,核心是对比分裂前后目标函数值的变化。

如果增益Gain>0,即分裂为两个叶⼦节点后,⽬标函数下降了,那么我们会考虑此次分裂的结果。

那么⼀直这样分裂,什么时候才会停⽌呢?

3.2 停⽌分裂条件判断

情况⼀:上节推导得到的打分函数是衡量树结构好坏的标准,因此,可⽤打分函数来选择最佳切分点。⾸先确定样本特征的所有切分点,对每⼀个确定的切分点进⾏切分,切分好坏的标准如下:

  • Gain表示单节点obj与切分后的两个节点的树obj之差,
  • 遍历所有特征的切分点,找到最⼤Gain的切分点即是最佳分裂点,根据这种⽅法继续切分节点,得到CART树。
  • γ 值设置的过⼤,则Gain为负,表示不切分该节点,因为切分后的树结构变差了。
    • γ 值越⼤,表示对切分后obj下降幅度要求越严,这个值可以在XGBoost中设定。

情况⼆:当树达到最⼤深度时,停⽌建树,因为树的深度太深容易出现过拟合,这⾥需要设置⼀个超参数max_depth。

情况三:当引⼊⼀次分裂后,重新计算新⽣成的左、右两个叶⼦结点的样本权重和。如果任⼀个叶⼦结点的样本权重低于某⼀个阈值,也会放弃此次分裂。这涉及到⼀个超参数:最⼩样本权重和,是指如果⼀个叶⼦节点包含的样本数量太少也会放弃分裂,防⽌树分的太细,这也是过拟合的⼀种措施。

4 XGBoostGDBT的区别

区别⼀:

  • XGBoost⽣成CART树考虑了树的复杂度,
  • GDBT未考虑,GDBT在树的剪枝步骤中考虑了树的复杂度。

区别⼆:

  • XGBoost是拟合上⼀轮损失函数的⼆阶导展开,GDBT是拟合上⼀轮损失函数的⼀阶导展开,因此,XGBoost的准确性更⾼,且满⾜相同的训练效果,需要的迭代次数更少。

区别三:

  • XGBoost与GDBT都是逐次迭代来提⾼模型性能,但是XGBoost在选取最佳切分点时可以开启多线程进⾏,⼤⼤提⾼了运⾏速度。

 

xgboost算法api介绍

1 xgboost的安装:

官⽹链接:https://xgboost.readthedocs.io/en/latest/

pip install xgboost

2 xgboost参数介绍

xgboost虽然被称为kaggle⽐赛神奇,但是,我们要想训练出不错的模型,必须要给参数传递合适的值。

XGBoost 的参数分为三类:

  1. 通用参数(General Parameters):控制整体框架,控制模型宏观运行逻辑,影响整体计算流程。

  2. Booster 参数(Booster Parameters):根据 booster 类型(树模型 / 线性模型),控制每一步 Booster 的训练细节。

  3. 学习目标参数(任务参数)(Task Parameters):控制训练目标与评估

1、通用参数(General Parameters)

参数名 缺省值 说明
booster gbtree 选择 Booster 类型(弱学习器类型):gbtree(树模型,推荐)、gblinear(线性模型)、dart(带 Dropout 的树模型)
verbosity 1

日志详细程度:
• 0:静默模式
• 1:警告信息
• 2:调试信息

nthread 系统最大可用线程数最大CPU核心数

并行线程数,建议不超过 CPU 核心数,默认自动检测并使用全部核心

num_pbuffer XGBoost 自动设置 预测结果缓存大小(无需用户设置,自动适配训练样本数)(通常=训练样本数)该缓存⽤于保存最后boosting操作的预测结果。
num_feature XGBoost 自动设置 模型使用的特征维度(无需用户设置,自动适配数据最大特征数)在boosting中使⽤特征的维度,设置为特征的最⼤维度
 

⚠️ 注意

  • silent 参数已废弃,由 verbosity 替代

  • num_pbuffer 和 num_feature 无需手动设置

2、 Booster 参数

根据 booster 类型(树模型 / 线性模型),控制每一步 Booster 的训练细节。

2.1 树模型参数(booster=gbtree/dart

参数 别名 缺省值 说明 范围
eta learning_rate 0.3 学习率:缩小每步权重更新,防止过拟合 [0, 1]
gamma min_split_loss 0 分裂所需最小损失下降值(值越大越保守) [0, ∞)
max_depth - 6 树的最大深度(0=无限制) [0, ∞)
min_child_weight - 1 叶节点最小样本权重和(值越大越保守)当它的值较⼤时,可以避免模型学习到局部的特殊样本。 但是如果这个值过⾼,会导致⽋拟合。这个参数需要使⽤CV来调整。 [0, ∞)
subsample - 1 样本随机采样比例(防止过拟合)

减⼩这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过⼩,它可能会导致⽋拟合。

典型值:0.5-1,0.5代表平均采样,防⽌过拟合.

(0, 1]
colsample_bytree - 1 每棵树列(特征)采样比例

⽤来控制每棵随机采样的列数的占⽐(每⼀列是⼀个特征)。

典型值:0.5-1

(0, 1]
colsample_bylevel - 1 每层分裂时列采样比例

⽤来控制树的每⼀级的每⼀次分裂,对列数的采样的占⽐。

我个⼈⼀般不太⽤这个参数,因为subsample参数和colsample_bytree参数可以起到相同的作⽤。但是如果感

兴趣,可以挖掘这个参数更多的⽤处。

(0, 1]
lambda reg_lambda 1 L2正则化系数(权重惩罚)

权重的L2正则化项(和Ridge regression类似)。

这个参数是⽤来控制XGBoost的正则化部分的。虽然⼤部分数据科学家很少⽤到这个参数,但是这个参数在减少过拟合上还是可以挖掘出更多⽤处的。

[0, ∞)
alpha reg_alpha 0 L1正则化系数(特征选择)权重的L1正则化项。(和Lasso regression类似)。 可以应⽤在很⾼维度的情况下,使得算法的速度更快。 [0, ∞)
scale_pos_weight - 1

样本不平衡时使用
建议设为 负样本数/正样本数

在各类别样本⼗分不平衡时,把这个参数设定为⼀个正值,可以使算法更快收敛。通常可以将其设置为负样本的数⽬与正样本数⽬的⽐值。

(0, ∞)

2.2 线性模型参数(booster=gblinear

linear booster⼀般很少⽤到。

参数 别名 缺省值 说明
lambda reg_lambda 0

L2正则化惩罚系数,增加该值会使得模型更加保守。

alpha reg_alpha 0 L1正则化惩罚系数,增加该值会使得模型更加保守。

⚠️ 注意

  • lambda_bias 参数已废弃(最新版移除)

  • dart 模式额外支持 rate_drop(丢弃率)和 skip_drop(跳过丢弃概率)

 

3、学习目标参数(Task Parameters)

控制训练目标(如分类 / 回归任务、评估指标等)。

 

参数名 缺省值 说明 可选值 / 示例
objective reg:squarederror 定义训练任务类型(目标函数)

回归:reg:squarederror

分类:binary:logistic/multi:softmax(需配 num_class

reg:squarederror - 均方误差回归(替代旧版 reg:linear) 

binary:logistic - 二分类概率输出 ,⼆分类逻辑回归,输出为概率

multi:softmax - 多分类类别预测(需设 num_class) 使⽤softmax的多分类器,返回预测的类别(不是概率)。 

multi:softprob - 多分类概率输出(需设 num_class)  和multi:softmax参数⼀样,但是返回的是每个数据属于各个类别的概率。

eval_metric 随 objective 自动选择 评估指标,需与任务匹配

回归:rmse/mae

分类:logloss/auc

多分类:merror/mlogloss

rmse”: 均⽅根误差

mae”: 平均绝对值误差

logloss”: 负对数似然函数值

error”: ⼆分类错误率。(阈值=0.5)

    • 其值通过错误分类数⽬与全部分类数⽬⽐值得到。对于预测,预测值⼤于0.5被认为是正类,其它归为负类。

error@t”: 自定义阈值(如 error@0.6)不同的划分阈值可以通过 ‘t’进⾏设置

merror”: 多分类错误率,计算公式为(wrong cases)/(all cases)

mlogloss”: 多分类log损失

auc”: 曲线下的⾯积

seed 0 随机数种子,固定后可复现结果 -

 

关键参数关联与实践建议

  1. 树模型核心调优eta(学习率)+ max_depth(树深)+ gamma(分裂阈值)+ subsample/colsample_bytree(采样),通过交叉验证(CV)组合调整,平衡欠拟合与过拟合。
  2. 正则化控制lambda(L2)+ alpha(L1),高维数据优先用 alpha 加速,常规场景用 lambda 平滑权重。
  3. 类别不平衡scale_pos_weight 设为「负样本数 / 正样本数」,配合 eval_metric=auc 或 logloss 优化。
  • 防过拟合:降低 max_depth、提高 min_child_weight、减小 eta

  • 不平衡数据:调整 scale_pos_weight

  • 特征多样性:使用 colsample_bytree 和 subsample

xgboost案例介绍

1 案例背景

该案例和前⾯决策树中所⽤案例⼀样。

泰坦尼克号沉没是历史上最臭名昭着的沉船事件之⼀。1912年4⽉15⽇,在她的处⼥航中,泰坦尼克号在与冰⼭相撞后沉没,在2224名乘客和机组⼈员中造成1502⼈死亡。这场耸⼈听闻的悲剧震惊了国际社会,并为船舶制定了更好的安全规定。 造成海难失事的原因之⼀是乘客和机组⼈员没有⾜够的救⽣艇。尽管幸存下沉有⼀些运⽓因素,但有些⼈⽐其他⼈更容易⽣存,例如妇⼥,⼉童和上流社会。 在这个案例中,我们要求您完成对哪些⼈可能存活的分析。特别是,我们要求您运⽤机器学习⼯具来预测哪些乘客幸免于悲剧。

案例:https://www.kaggle.com/c/titanic/overview

我们提取到的数据集中的特征包括票的类别,是否存活,乘坐班次,年龄,登陆home.dest,房间,船和性别等。

数据(需要梯子):http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt

如果上述链接失效,建议之前使用:D:\learn\000人工智能数据大全\经典数据集\泰坦尼克号\train.csv

  PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S

经过观察数据得到:

  • 1 乘坐班是指乘客班(123),是社会经济阶层的代表。
  • 2 其中age数据存在缺失。

2 步骤分析

  • 1.获取数据
  • 2.数据基本处理
    • 2.1 确定特征值,⽬标值
    • 2.2 缺失值处理
    • 2.3 数据集划分
  • 3.特征⼯程(字典特征抽取)
  • 4.机器学习(xgboost)
  • 5.模型评估

3 代码实现

# 获取数据
data=pd.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')
# 确定目标值特征值
x=data[['Pclass','Sex','Age']]
y=data['Survived']
# 缺失数据处理
# x['Age'].isnull().any()#True
# x['Age'].isnull().sum()#177
x.loc[:,'Age']=x['Age'].fillna(x['Age'].mean())
# 数据拆分测试集训练集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=66)
# 对性别特征进行onehot编码
# 特征⼯程(字典特征抽取)
# 特征中出现类别符号,需要进⾏one-hot编码处理(DictVectorizer)
# x.to_dict(orient="records") 需要将数组特征转换成字典数据
transformer=DictVectorizer(sparse=False)
x_train_onehot=transformer.fit_transform(x_train.to_dict(orient='records'))
x_test_onehot=transformer.transform(x_test.to_dict(orient='records'))
# 模型训练
xg=XGBClassifier()
xg.fit(x_train_onehot,y_train)
print(xg.score(x_test_onehot,y_test))
# 针对max_depth进⾏模型调优
depth_range = range(15)
scores=[]
for i in depth_range:
    xg=XGBClassifier(eta=1, gamma=0, max_depth=i)
    xg.fit(x_train_onehot,y_train)
    s=xg.score(x_test_onehot,y_test)
    scores.append(s)
    print(s)
plt.plot(depth_range,scores)
plt.show()
查看打印结果
0.7877094972067039
0.7877094972067039
0.7988826815642458
0.7932960893854749
0.770949720670391
0.770949720670391
0.7486033519553073
0.776536312849162
0.7877094972067039
0.7877094972067039
0.7932960893854749
0.7877094972067039
0.7877094972067039
0.776536312849162
0.7877094972067039
0.7877094972067039

otto案例(产品分类)

1.案例背景介绍参照:kaggle-奥托集团产品分类挑战赛

2 思路分析

1.数据获取

2.数据基本处理

  • 2.1 截取部分数据
  • 2.2 把标签纸转换为数字
  • 2.3 分割数据(使⽤StratifiedShuffleSplit)
  • 2.4 数据标准化
  • 2.5 数据pca降维

3.模型训练

  • 3.1 基本模型训练
  • 3.2 模型调优
  • 3.2.1 调优参数:
    • n_estimator,
    • max_depth,
    • min_child_weights,
    • subsamples,
    • consample_bytrees,
    • etas
  • 3.2.2 确定最后最优参数

代码实现

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 数据获取
data=pd.read_csv(r"D:\learn\000人工智能数据大全\经典数据集\奥托集团产品分类挑战赛\train.csv")
# 图形可视化,查看数据分布
import seaborn as sns
sns.countplot(x=data.target)
plt.show()

由上图可以看出,该数据类别不均衡,所以需要后期处理

# 数据基本处理
#数据已经经过脱敏,不再需要特殊处理
## 截取部分数据
# 随机欠采样获取数据
# 首先需要确定特征值\标签值

y = data["target"]
x = data.drop(["id", "target"], axis=1)
# 欠采样获取数据
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(random_state=0)
X_resampled, y_resampled = rus.fit_resample(x, y)
x.shape, y.shape#((61878, 93), (61878,))
X_resampled.shape, y_resampled.shape#((17361, 93), (17361,))
# 图形可视化,查看数据分布
import seaborn as sns
sns.countplot(x=y_resampled)
plt.show()

## 把标签值转换为数字
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y_resampled = le.fit_transform(y_resampled)
## 分割数据
from sklearn.model_selection import StratifiedShuffleSplit
# 创建划分器:进行1次划分
sss=StratifiedShuffleSplit(n_splits=1,random_state=66,test_size=0.2)
# 获取划分索引 (单次循环)
for train_index,test_index in sss.split(X_resampled.values,y_resampled):
    x_train,x_test=X_resampled.values[train_index],X_resampled.values[test_index]
    y_train,y_test=y_resampled[train_index],y_resampled[test_index]
#分割数据可视化 
import seaborn as sns
plt.figure(figsize=(20,8))
sns.countplot(x=y_test)
plt.show()

上面的数据分割,是分层采用,保证分割后所有的数据和原来的数据占比保持一致,下面是train_test_split的对比:

from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(X_resampled,y_resampled,test_size=0.2,random_state=55)
 #分割数据可视化 
import seaborn as sns
plt.figure(figsize=(20,8))
sns.countplot(x=y_test)
plt.show()

# 标准化
from sklearn.preprocessing import StandardScaler
standar=StandardScaler()
x_train_standar=standar.fit_transform(x_train)
x_test_standar=standar.transform(x_test)
# 数据pca降维
print(x_train.shape)#(13888, 93)
from sklearn.decomposition import PCA

pca=PCA(n_components=0.9)
x_train_standar_pca=pca.fit_transform(x_train_standar)
x_test_standar_pca=pca.transform(x_test)
x_train_standar_pca.shape#(13888, 65)
# 从上⾯输出的数据可以看出,只选择65个元素,就可以表达出特征中90%的信息

# 降维数据可视化
plt.plot(np.cumsum(pca.explained_variance_ratio_))
plt.xlabel("元素数量")
plt.ylabel("可表达信息的百分占比")
plt.show()

解读PCA降维可视化代码

1. pca.explained_variance_ratio_ - 获取主成分解释方差比

  • 功能​​:计算每个主成分解释的数据方差比例
  • ​解释​​:
    • 在PCA降维后,该属性返回一个数组
    • 每个元素代表该主成分(PC)所解释的数据变异百分比
    • 例如:[0.45, 0.30, 0.15, ...] 表示:
      • PC1解释45%的数据方差
      • PC2解释30%
      • PC3解释15%
  • 数学原理​​:

2. np.cumsum() - 计算累积和

  • 功能​​:计算累积解释方差比
  • ​解释​​:
    • 对主成分的方差比进行累加
    • 输入:[0.45, 0.30, 0.15]
    • 输出:[0.45, 0.75, 0.90]
    • 表示包含n个主成分时的累积解释能力
  • ​数学原理​​:
  • 其中  是第 i 个主成分的解释方差

完整代码示例

# 1. 拟合PCA模型
pca = PCA().fit(X_scaled)

# 2. 计算累积解释方差
cum_var = np.cumsum(pca.explained_variance_ratio_)

# 3. 创建可视化
plt.figure(figsize=(10, 6))
plt.plot(cum_var, 'o-', linewidth=2)
plt.title('PCA Cumulative Explained Variance')
plt.xlabel("元素数量")
plt.ylabel("可表达信息的百分占比")
plt.grid(True, linestyle='--', alpha=0.7)

# 4. 标识关键阈值点(可选)
plt.axhline(y=0.95, color='r', linestyle='--')  # 95%方差线
plt.axvline(x=np.where(cum_var >= 0.95)[0][0], 
            color='g', linestyle=':')  # 对应主成分数

plt.show()
    • 常用阈值:95%(科学研究)或 85%(工程应用)
    • 平衡维度压缩与信息保留

应用场景举例

  1. ​维度选择​​:

    • 确定应保留多少主成分降低维度
    • 避免过度降维造成信息损失
    • 防止降维不足导致维度诅咒
  2. ​数据探索​​:

    • 评估数据的固有维度
    • 若10个主成分解释95%方差 ⇒ 数据可用10维表示
  3. ​模型优化​​:

    • 在主成分空间进行机器学习
    • 避免维度灾难,提高效率
    • 示例:人脸识别中仅保留前150个主成分

注意事项

  1. ​数据预处理要求​​:

    • PCA对特征尺度敏感
    • 务必先进行​​标准化​​(均值中心化+方差缩放)
    • 错误:PCA().fit(X)
    • 正确:PCA().fit(StandardScaler().fit_transform(X))
  2. ​主成分排序​​:

    • PCA自动按解释方差降序排列
    • PC1的解释能力最强,依次递减
  3. ​特殊数据处理​​:

    • 对于稀疏数据使用TruncatedSVD
    • 非线性数据考虑KernelPCA
#3 .模型训练
# 3.1 基本模型训练
from xgboost import XGBClassifier
XGB=XGBClassifier()
XGB.fit(x_train_standar_pca,y_train)
# 改变预测值的输出模式,让输出结果为百分占⽐,降低logloss值
pre_proba=XGB.predict_proba(x_test_standar_pca)
# logloss进⾏模型评估
from sklearn.metrics import log_loss
loss=log_loss(y_test,pre_proba,normalize=True)
print(loss)
XGB.get_params()
# 3.2 模型调优
# 3.2.1 调优参数:
# n_estimator
losses=[]
params=[100,200,400,450,500,550,600,700]
for p in params:
    XGB=XGBClassifier(max_depth=3,
                        learning_rate=0.1,
                        n_estimators=p,
                        objective="multi:softprob",
                        n_jobs=-1,
                        nthread=4,
                        min_child_weight=1,
                        subsample=1,
                        colsample_bytree=1,
                        seed=42)
    XGB.fit(x_train_standar_pca,y_train)
    # 改变预测值的输出模式,让输出结果为百分占⽐,降低logloss值
    pre_proba=XGB.predict_proba(x_test_standar_pca)
    # logloss进⾏模型评估
    loss=log_loss(y_test,pre_proba,normalize=True)
    losses.append(loss)
plt.plot(params,losses,'o-')
plt.xlabel('n_estimator')
plt.ylabel('loss')
plt.show()
print("n_estimators的最优值为:",params[np.argmin(losses)])#n_estimators的最优值为: 200


# 3.2.1 调优参数:
# max_depth
losses=[]
params=[1,3,5,6,7]
for p in params:
    XGB=XGBClassifier(max_depth=p,
                        learning_rate=0.1,
                        n_estimators=200,
                        objective="multi:softprob",
                        n_jobs=-1,
                        nthread=4,
                        min_child_weight=1,
                        subsample=1,
                        colsample_bytree=1,
                        seed=42)
    XGB.fit(x_train_standar_pca,y_train)
    # 改变预测值的输出模式,让输出结果为百分占⽐,降低logloss值
    pre_proba=XGB.predict_proba(x_test_standar_pca)
    # logloss进⾏模型评估
    loss=log_loss(y_test,pre_proba,normalize=True)
    losses.append(loss)
plt.plot(params,losses,'o-')
plt.xlabel('max_depth')
plt.ylabel('loss')
plt.show()
print("max_depth的最优值为:",params[np.argmin(losses)])#max_depth的最优值为: 3

# 依次对下面的参数进行调优
# in_child_weights,
# 依据上⾯模式进⾏调整
# subsamples,
# consample_bytrees,
# etas
# 3.2.2 确定最后最优参数
xgb = XGBClassifier(learning_rate =0.1,
n_estimators=200,
max_depth=3,
min_child_weight=3,
subsample=0.7,
colsample_bytree=0.7,
nthread=4,
seed=42,
objective='multi:softprob')
xgb.fit(x_train_standar_pca,y_train)
y_pre = xgb.predict_proba(x_test_standar_pca)
print("测试数据的logloss值为 : {}".format(log_loss(y_test, y_pre, normalize=True)))#测试数据的logloss值为 : 0.8638121335535889

总结

XGBoost=二阶泰勒展开+boosting+决策树+正则化

  • 面试题:了解XGBoost么,请详细说说它的原理

回答要点:二阶泰勒展开,boosting,决策树,正则化

  • Boosting:XGBoost使用Boosting提升思想对多个弱学习器进行迭代式学习
  • 二阶泰勒展开:每一轮学习中,XGBoost对损失函数进行二阶泰勒展开,使用一阶和二阶梯度进行优化。
  • 决策树:在每一轮学习中,XGBoost使用决策树算法作为弱学习进行优化。
  • 正则化:在优化过程中XGBoost为防止过拟合,在损失函数中加入惩罚项,限制决策树的叶子节点个数以及决策树叶子节点的值。

lightGBM

1.1 lightGBM演进过程

1.2 AdaBoost算法

AdaBoost是⼀种提升树的⽅法,和三个臭⽪匠,赛过诸葛亮的道理⼀样。

AdaBoost两个问题:

  • (1) 如何改变训练数据的权重或概率分布
    • 提⾼前⼀轮被弱分类器错误分类的样本的权重,降低前⼀轮被分对的权重
  • (2) 如何将弱分类器组合成⼀个强分类器,亦即,每个分类器,前⾯的权重如何设置
    • 采取”多数表决”的⽅法.加⼤分类错误率⼩的弱分类器的权重,使其作⽤较⼤,⽽减⼩分类错误率⼤的弱分类器的权重,使其在表决中起较⼩的作⽤。

1.3 GBDT算法以及优缺点

GBDT和AdaBosst很类似,但是⼜有所不同。

  • GBDT和其它Boosting算法⼀样,通过将表现⼀般的几个模型(通常是深度固定的决策树)组合在⼀起来集成⼀个 表现较好的模型。
  • AdaBoost是通过提升错分数据点的权重来定位模型的不足, Gradient Boosting通过负梯度来识别问题,通过计算负梯度来改进模型,即通过反复地选择⼀个指向负梯度⽅向的函数,该算法可被看做在函数空间⾥对⽬标函数进⾏优化。

缺点:

GBDT ->预排序⽅法(pre-sorted)

  • (1) 空间消耗⼤
    • 这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如排序后的索引,为了后续快速的计算分割点),这⾥需要消耗训练数据两倍的内存
  • (2) 时间上也有较⼤的开销。
    • 在遍历每⼀个分割点的时候,都需要进⾏分裂增益的计算,消耗的代价⼤。
  • (3) 对内存(cache)优化不友好。
    • 在预排序后,特征对梯度的访问是⼀种随机访问,并且不同的特征访问的顺序不⼀样,⽆法对cache进⾏优化。
    • 同时,在每⼀层⻓树的时候,需要随机访问⼀个⾏索引到叶⼦索引的数组,并且不同特征访问的顺序也不⼀样,也会造成较⼤的cache miss。

1.4 启发

常⽤的机器学习算法,例如神经⽹络等算法,都可以以mini-batch的⽅式训练,训练数据的大小不会受到内存限制。

⽽GBDT在每⼀次迭代的时候,都需要遍历整个训练数据多次。

如果把整个训练数据装进内存则会限制训练数据的⼤⼩;如果不装进内存,反复地读写训练数据⼜会消耗⾮常⼤的时间。

尤其⾯对⼯业级海量的数据,普通的GBDT算法是不能满⾜其需求的。

LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地⽤于⼯业实践。

2 什么是lightGBM

lightGBM是2017年1⽉,微软在GItHub上开源的⼀个新的梯度提升框架。

github介绍链接

在开源之后,就被别⼈冠以“速度惊⼈”、“⽀持分布式”、“代码清晰易懂”、“占⽤内存⼩”等属性。

LightGBM主打的⾼效并⾏训练让其性能超越现有其他boosting⼯具。在Higgs数据集上的试验表明,LightGBM⽐XGBoost快将近10倍,内存占⽤率⼤约为XGBoost的1/6。

higgs数据集介绍:这是⼀个分类问题,⽤于区分产⽣希格斯玻⾊⼦的信号过程和不产⽣希格斯玻⾊⼦的信号过程。

数据链接

3 lightGBM原理

lightGBM 主要基于以下方面优化,提升整体特特性:

  1. 基于Histogram(直⽅图)的决策树算法
  2. Lightgbm 的Histogram(直⽅图)做差加速
  3. 带深度限制的Leaf-wise的叶⼦⽣⻓策略
  4. 直接⽀持类别特征
  5. 直接⽀持⾼效并⾏

具体解释⻅下,分节介绍。

3.1 基于Histogram(直方图)的决策树算法

直⽅图算法的基本思想是

  • 把连续的浮点特征值离散化成k个整数,同时构造⼀个宽度为k的直⽅图。
  • 在遍历数据的时候,根据离散化后的值作为索引在直⽅图中累积统计量,当遍历⼀次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。

Eg:

[0, 0.1) --> 0;

[0.1,0.3) --> 1;

...

使⽤直⽅图算法有很多优点。⾸先,最明显就是内存消耗的降低,直⽅图算法不仅不需要额外存储预排序的结果,⽽且可以只保存特征离散化后的值,⽽这个值⼀般⽤8位整型存储就⾜够了,内存消耗可以降低为原来的1/8。

然后在计算上的代价也大幅降低,预排序算法每遍历⼀个特征值就需要计算⼀次分裂的增益,⽽直⽅图算法只需要计算k次(k可以认为是常数),时间复杂度从O(#data#feature)优化到O(k#features)。

当然,Histogram算法并不是完美的。由于特征被离散化后,找到的并不是很精确的分割点,所以会对结果产⽣影响。

但在不同的数据集上的结果表明,离散化的分割点对最终的精度影响并不是很⼤,甚⾄有时候会更好⼀点。原因是决策树本来就是弱模型,分割点是不是精确并不是太重要;较粗的分割点也有正则化的效果,可以有效地防⽌过拟合;即使单棵树的训练误差⽐精确分割的算法稍⼤,但在梯度提升(Gradient Boosting)的框架下没有太⼤的影响。

3.2 Lightgbm Histogram(直方图)做差加速

⼀个叶⼦的直⽅图可以由它的⽗亲节点的直⽅图与它兄弟的直⽅图做差得到。

通常构造直⽅图,需要遍历该叶⼦上的所有数据,但直⽅图做差仅需遍历直⽅图的k个桶。

利⽤这个⽅法,LightGBM可以在构造⼀个叶⼦的直⽅图后,可以⽤⾮常微⼩的代价得到它兄弟叶⼦的直⽅图,在速度上可以提升⼀倍。

3.3 带深度限制的Leaf-wise的叶⼦⽣⻓策略

Level-wise遍历⼀次数据可以同时分裂同⼀层的叶⼦,容易进⾏多线程优化,也好控制模型复杂度,不容易过拟合。

  • 但实际上Level-wise是⼀种低效的算法,因为它不加区分的对待同⼀层的叶⼦,带来了很多没必要的开销,因为实际上很多叶⼦的分裂增益较低,没必要进⾏搜索和分裂。

Leaf-wise则是⼀种更为⾼效的策略,每次从当前所有叶⼦中,找到分裂增益最⼤的⼀个叶⼦,然后分裂,如此循环。

  • 因此同Level-wise相⽐,在分裂次数相同的情况下,Leaf-wise可以降低更多的误差,得到更好的精度。
  • Leaf-wise的缺点是可能会⻓出⽐较深的决策树,产⽣过拟合。因此LightGBM在Leaf-wise之上增加了⼀个最⼤深度的限制,在保证⾼效率的同时防⽌过拟合。

3.4 直接支持类别特征

实际上⼤多数机器学习⼯具都⽆法直接⽀持类别特征,⼀般需要把类别特征,转化到多维的0/1特征,降低了空间和时间的效率。

⽽类别特征的使⽤是在实践中很常⽤的。基于这个考虑,LightGBM优化了对类别特征的⽀持,可以直接输⼊类别特征,不需要额外的0/1展开。并在决策树算法上增加了类别特征的决策规则。

在Expo数据集上的实验,相⽐0/1展开的⽅法,训练速度可以加速8倍,并且精度⼀致。⽬前来看,LightGBM是第⼀个直接⽀持类别特征的GBDT⼯具。

Expo数据集介绍:数据包含1987年10⽉⾄2008年4⽉美国境内所有商业航班的航班到达和离开的详细信息。这是⼀个庞⼤的数据集:总共有近1.2亿条记录。主要⽤于预测航班是否准时。

数据链接

 

3.5 直接支持高效并行

LightGBM还具有⽀持⾼效并⾏的优点。LightGBM原⽣⽀持并⾏学习,⽬前⽀持特征并⾏和数据并⾏的两种。

  • 特征并⾏的主要思想是在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。
  • 数据并⾏则是让不同的机器先在本地构造直⽅图,然后进⾏全局的合并,最后在合并的直⽅图上⾯寻找最优分割点。

LightGBM针对这两种并⾏⽅法都做了优化:

  • 特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信;

  • 数据并⾏中使⽤分散规约 (Reduce scatter) 把直⽅图合并的任务分摊到不同的机器,降低通信和计算,并利⽤直⽅图做差,进⼀步减少了⼀半的通信量。

  • 基于投票的数据并行(Voting Parallelization)则进⼀步优化数据并⾏中的通信代价,使通信代价变成常数级别。在数据量很⼤的时候,使⽤投票并⾏可以得到⾮常好的加速效果。

 

LightGBM优势

  • 基于Histogram(直⽅图)的决策树算法
  • Lightgbm 的Histogram(直⽅图)做差加速
  • 带深度限制的Leaf-wise的叶⼦⽣⻓策略
  • 直接⽀持类别特征
  • 直接⽀持⾼效并⾏

lightGBM算法api介绍

1 lightGBM的安装

一、核心功能参数(Core Parameters)

控制模型 任务类型、算法框架、迭代逻辑 的基础参数,决定模型 “大方向”。

参数名 含义与作用 典型用法示例
task 定义模型任务,区分训练 / 预测阶段(新版仍保留基础逻辑,但更多通过流程控制替代) task='train'(训练)/'predict'(预测)
objective 模型目标函数,替代旧版 application,明确任务类型(分类 / 回归等) - 二分类:objective='binary'
- 多分类:objective='multiclass'
- 回归:objective='regression'
boosting_type 选择提升算法框架,替代旧版 boosting,决定模型集成方式 - GBDT:boosting_type='gbdt'
- 随机森林风格:boosting_type='rf'
- DART:boosting_type='dart'
- GOSS:boosting_type='goss'
n_estimators 最大迭代次数(树的数量),控制模型复杂度与训练时长 常规任务设 n_estimators=100~1000(可结合早停优化)
learning_rate 学习率(步长),控制每棵树对模型的贡献幅度,平衡收敛速度与精度 初始设 learning_rate=0.1,小数据集 / 精细调参用 0.01 等更小值

常⽤ 0.1, 0.001, 0.003…

metric 评估指标,训练时监控模型表现(支持多指标) - 二分类:metric='binary_logloss'
- 多分类:metric='multi_logloss'
- 回归:metric='mse'/'mae'

二、树结构控制参数(Control Parameters)

精细调节 单棵树的生长规则 ,直接影响模型复杂度、过拟合风险。

参数名 含义与作用 调参逻辑与建议
max_depth 树的最大深度,限制树生长的纵向复杂度 - 过拟合时减小(如 max_depth=3~8);
- 低拟合时适度增大,但需配合其他参数
num_leaves 单棵树的最大叶子节点数(LightGBM 特色参数,比 max_depth 更直接控制复杂度) 建议满足 num_leaves ≤ 2^max_depth(否则易过拟合),默认 31,可试 63/127 等
min_data_in_leaf 叶子节点所需最小样本数,防止树过深 / 过拟合

- 过拟合时增大(如 min_data_in_leaf=50~500,大数据集可更高);
- 低拟合时减小

- 默认20

min_gain_to_split 分裂所需最小增益(Gain),控制 “有用分裂” 的阈值 增大可简化树结构(减少分裂),防止过拟合;默认 0,可试 0.1/0.5
lambda_l1/lambda_l2 L1/L2 正则化系数,对叶子节点权重做正则,抑制过拟合 从 0 开始,过拟合时逐步增大(如 lambda_l2=0.1~10

三、采样与加速参数(Sampling & Speed)

通过 特征 / 样本采样 加速训练、增强模型鲁棒性,平衡速度与泛化能力。

参数名 含义与作用 调参场景
feature_fraction

每次迭代随机选特征的比例(类似随机森林的特征子采样)

例如 为0.8时,意味着在每次迭代中随机选择80%的参数来建树

- 加速训练:feature_fraction=0.5~0.8
- 防过拟合:结合 boosting_type='rf' 使用
bagging_fraction

每次迭代随机选样本的比例(样本子采样):每次迭代时⽤的数据⽐例

 

加速 + 防过拟合,需配合 bagging_freq(采样频率,0 表示禁用,>0 表示每 k 次迭代采样)

max_bin

特征离散化的最大分箱数,影响特征处理精度与训练速度。

表示 feature 将存⼊的 bin 的最⼤数量

- 加速:减小(如 max_bin=32/64);
- 提精度:增大(如 max_bin=255),但需更多内存
device 计算设备选择,支持 'cpu'/'gpu'(需 GPU 版本支持) 有 GPU 时设 device='gpu' 加速训练

四、IO 与数据处理参数(IO Parameters)

控制 数据输入输出、特征类型识别 的细节,影响数据加载效率与特征利用。

参数名 含义与作用 用法示例
categorical_feature

声明分类特征列(索引列表),LightGBM 会自动优化处理(如特殊分裂规则)

如果 categorical_features = 0,1,2, 则列 0,1,2是 categorical 变量

categorical_feature=[0,1,2](指定第 0、1、2 列为分类特征)
ignore_column

完全忽略某些列(不参与训练),替代手动预处理删除列

与 categorical_features 类似,只不过不是将特定的列视为categorical,⽽是完全忽略

ignore_column=[3,4](忽略第 3、4 列)
save_binary 启用后将数据集保存为二进制格式,加速后续加载 save_binary=True(训练后生成 .bin 文件,下次直接加载)

五、调参策略速查表

结合 训练速度、精度、过拟合 三大目标,快速匹配参数调整方向:

目标 核心参数调整建议
更快训练(Faster Speed)

- 减小 max_bin(如 32/64
- 启用 feature_fraction(用feature_fraction来做sub-sampling)(如 0.5
- 启用 bagging_fraction+bagging_freq(用bagging_fraction和 bagging_freq 【bagging的次数。0表示禁⽤bagging,⾮零值表示执⾏k次bagging】)
- 设 save_binary=True 加速数据加载

⽤ parallel learning

更高精度(Better Accuracy) - 增大 max_bin(如 255
- 适度增大 num_leaves(但需 ≤ 2^max_depth)
- 减小 learning_rate+ 增大 n_estimators(如 learning_rate=0.01+n_estimators=2000
- 用更多训练数据
抑制过拟合(Over-fitting)

- 减小 max_bin/num_leaves
- 增大 min_data_in_leaf(将它设置为较⼤的值可以避免⽣⻓太深的树,但可能会导致 underfitting,在⼤型数据集时就设置为数百或数千)/min_gain_to_split
- 增大 lambda_l1/lambda_l2 正则
- 启用 feature_fraction/bagging_fraction和 bagging_freq 做采样

training data 多⼀些

⽤ max_depth 控制树的深度


六、关键实践 Tips

  1. 早停(Early Stopping):结合 eval_set+early_stopping_rounds,用验证集监控,自动终止无效迭代(如 early_stopping_rounds=50)。
  2. 参数优先级num_leaves 对复杂度影响比 max_depth 更直接,调参优先试 num_leaves
  3. 分类特征处理:务必用 categorical_feature 声明分类列,LightGBM 会针对性优化(比手动编码更高效)。

如需更细节的参数默认值、极端场景调优,可直接参考 LightGBM 官方参数文档 ,结合业务场景(如金融风控、推荐系统等)做针对性实验即可。
 

lightGBM案例介绍

接下来,通过鸢尾花数据集对lightGBM的基本使⽤,做⼀个介绍。

# 加载数据,对数据进⾏基本处理
data=load_iris()
x=data.data
y=data.target
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
# 模型训练
gbm = lgb.LGBMRegressor(objective='regression', learning_rate=0.05, n_estimators=200)
# gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1',early_stopping_rounds=5)
#​​ 自LightGBM 3.0版本起,early_stopping_rounds参数已从模型构造函数移至fit()方法的callbacks参数中。需要​​使用回调函数实现早停​​。
#启用早停需要:必须设置足够大的n_estimators​​:n_estimators=1000  # 初始值需大于早停轮数
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1',callbacks=[lgb.early_stopping(stopping_rounds=5)])
print(f"实际使用迭代次数: {gbm.best_iteration_}")  # 早停发生的轮次
print(f"最佳验证分数: {gbm.best_score_['valid_0']['l1']}")
gbm.score(X_test, y_test)
# 0.810605595102488
点击查看打印结果
[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000028 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 87
[LightGBM] [Info] Number of data points in the train set: 120, number of used features: 4
[LightGBM] [Info] Start training from score 0.975000
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Training until validation scores don't improve for 5 rounds
[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
Early stopping, best iteration is:
[92]	valid_0's l1: 0.0909559	valid_0's l2: 0.0403314
实际使用迭代次数: 92
最佳验证分数: 0.09095594373649211
0.9415486955284025

当然,如果最大迭代次数设置过小,也会无法触发早停:

gbm = lgb.LGBMRegressor(objective='regression', learning_rate=0.05, n_estimators=10)

# ⽹格搜索,参数优化
estimator = lgb.LGBMRegressor(num_leaves=31)
param_grid = {
'learning_rate': [0.01, 0.1, 1],
'n_estimators': [20, 40]
}
gbm = GridSearchCV(estimator, param_grid, cv=4)
gbm.fit(X_train, y_train)
print('Best parameters found by grid search are:', gbm.best_params_)
# Best parameters found by grid search are: {'learning_rate': 0.1, 'n_estimators': 40}

模型调优训练

gbm = lgb.LGBMRegressor(num_leaves=31, learning_rate=0.1, n_estimators=40)
gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', callbacks=[lgb.early_stopping(stopping_rounds=5)])
gbm.score(X_test, y_test)
# 0.9536626296481988

lightgbm综合案例:

《绝地求生》玩家排名预测

 

当前最流行的集成学习框架分析

🔥 最流行且实用的集成学习框架

当前工业界最流行的集成学习框架主要有三个主流选择:

  1. ​XGBoost (eXtreme Gradient Boosting)​

    • 仍然是最广泛使用的框架之一
    • 在Kaggle竞赛中多年占据主导地位
    • GitHub stars: 24.5k+
  2. ​LightGBM (Light Gradient Boosting Machine)​

    • 微软开发的高效框架
    • 在工业界大规模应用占比快速提升
    • GitHub stars: 16.2k+
  3. ​CatBoost (Categorical Boosting)​

    • 由Yandex开发的强力框架
    • 专门优化了类别特征处理
    • GitHub stars: 7.5k+

🏆 实际工作中使用情况

根据2023年数据科学家调查报告和工业界实践:

框架 企业采用率 主要优势 典型应用场景
​LightGBM​ 约58% 极快的训练速度,低内存消耗 大规模数据,实时预测系统
​XGBoost​ 约46% 卓越的精度,丰富的特性 结构化数据竞赛,金融风控
​CatBoost​ 约32% 自动处理类别特征,鲁棒性强 用户行为预测,推荐系统
Scikit-Learn RF 30% 简单易用,集成方便 快速原型开发

注:总和超过100%因为很多公司使用多种框架

性能对比

# 基准测试数据(Microsoft, 2017)
+-----------------+-----------+------------+------------+
| Algorithm       | Accuracy  | Train Time | Memory Use |
+-----------------+-----------+------------+------------+
| XGBoost         | 92.1%     | 38min      | 15.2GB     |
| LightGBM        | 92.3%     | 11min      | 4.3GB      |
| CatBoost        | 92.5%     | 22min      | 8.7GB      |
+-----------------+-----------+------------+------------+

XGBoost的深度分析

✅ XGBoost的优势

  1. ​卓越的性能表现​

    • 在结构化数据上的预测精度通常是最高的
    • 大量Kaggle竞赛获胜解决方案的核心算法
  2. ​丰富的功能​

    • 支持多种目标函数(回归/分类/排序)
    • 自定义损失函数
    • 正则化控制过拟合
    • 缺失值自动处理
  3. ​生态系统成熟​

    • 完善的文档和教程
    • 多种语言支持(Python/R/Java等)
    • 与MLflow等MLOps工具深度集成
  4. ​调优灵活性​

    • 丰富的超参数(50+)
    • 交叉验证内置支持
    • 提前停止功能

⚠️ XGBoost的局限

  1. ​内存消耗大​

    • 相比LightGBM内存使用更高
    • 不适合超大规模数据集(1亿+样本)
  2. ​训练速度较慢​

    • LightGBM通常比XGBoost快3-10倍
    • CatBoost在GPU上的优势明显
  3. ​特征工程需求高​

    • 对类别特征处理不如CatBoost智能
    • 需要手动特征编码

🚀 XGBoost在实际工作中的应用建议

  1. ​推荐使用场景​

    # 中小规模结构化数据(< 1000万样本)
    # 需要最高精度的预测任务
    # 传统行业(金融、医疗、制造业)
    from xgboost import XGBClassifier
    
    model = XGBClassifier(
        n_estimators=1000,
        learning_rate=0.05,
        max_depth=6,
        subsample=0.8,
        colsample_bytree=0.8,
        objective='binary:logistic',
        n_jobs=-1
    )
     
     
  2. ​替代方案考虑​

    # 大规模数据 → LightGBM
    import lightgbm as lgb
    
    # 大量类别特征 → CatBoost
    from catboost import CatBoostClassifier
    
    # 快速原型 → Scikit-learn GradientBoosting
    from sklearn.ensemble import GradientBoostingClassifier
     
     
  3. ​调优技巧​

    • 优先调优learning_rate, max_depth, n_estimators
    • 使用早停法确定最佳迭代次数
    model.fit(X_train, y_train,
              eval_set=[(X_val, y_val)],
              early_stopping_rounds=50,
              verbose=100)

现代集成学习框架最佳实践

  1. ​框架选择策略​

  2. ​生产部署优化​

    • 模型压缩(XGBoost pruning)
    • ONNX格式转换
    • 使用Triton Inference Server
  3. ​自动化ML集成​

    # 使用AutoGluon自动选择最优框架
    from autogluon.tabular import TabularPredictor
    predictor = TabularPredictor(label='target').fit(train_data)

应用场景​

场景 应用案例 模型选择
​金融风控​ 信用评分、反欺诈 XGBoost+严格特征解释
​广告CTR预测​ 点击率预估 LightGBM(大规模数据)
​推荐系统​ 个性化推荐 GBDT+LR混合模型
​医疗诊断​ 疾病预测 CatBoost(处理医疗分类变量)
​工业预测​ 设备故障预测 时间序列GB

总结建议

  1. ​首选框架​​:对于大多数工业场景,​​LightGBM是当前最实用、最高效的首选框架​​,平衡了速度、精度和资源消耗

  2. ​XGBoost定位​​:在精度要求极高的场景(如金融风控)和有成熟XGBoost基础设施的公司中,XGBoost仍是不可替代的选择

  3. ​新兴趋势​​:

    • CatBoost在类别特征多的场景表现卓越
    • 分布式版本(Dask-XGBoost, LightGBM on Spark)适合超大数据
    • 框架融合(ensemble of ensembles)成为高阶技术

建议学习路径:LightGBM → XGBoost → CatBoost → 定制集成

 

 

 

 

 

 

 

扩展内容

无偏估计

1.如何理解⽆偏估计

⽆偏估计:就是我认为所有样本出现的概率⼀样

假如有N种样本我们认为所有样本出现概率都是1/N。然后根据这个来计算数学期望。此时的数学期望就是我们平常讲的平均值。

数学期望本质就是平均值

2.⽆偏估计为何叫做⽆偏?它要估计什么?

⾸先回答第⼀个问题:它要“估计”什么?

  • 它要估计的是整体的数学期望(平均值)。

第⼆个问题:那为何叫做⽆偏?有偏是什么?

  • 假设这个是⼀些样本的集合X = x 1, x 2 , x 3, ..., x N,我们根据样本估计整体的数学期望(平均值)。

因为正常求期望是加权和,什么叫加权和这个就叫加权和。

每个样本出现概率不⼀样,概率⼤的乘起来就⼤,这个就产⽣偏重了(有偏估计)。

但是,但是我们不知道某个样本出现的概率啊。⽐如你从别⼈⼝袋⾥⾯随机拿了3张钞票。两张是⼗块钱,⼀张100元,然后你想估计下他⼝袋⾥的剩下的钱平均下来每张多少钱(估计平均值)。

然后呢?

⽆偏估计计算数学期望就是认为所有样本出现概率⼀样⼤,没有看不起哪个样本。

回到求钱的平均值的问题。⽆偏估计我们认为每张钞票出现概率都是1/2(因为只出现了10和100这两种情况,所以是1/2。如果是出现1 10 100三种情况,每种情况概率则是1/3。

哪怕拿到了两张⼗块钱,我还是认为⼗块钱出现的概率和100元的概率⼀样。不偏⼼。所以⽆偏估计,所估计的别⼈⼝袋每张钱的数学期望(平均值)= 10 ∗ 1/2 + 100 ∗ 1/2。

有偏估计那就是偏重那些出现次数多的样本。认为样本的概率是不⼀样的。

我出现了两次⼗块钱,那么我认为⼗块钱的概率是2/3,100块钱概率只有1/3. 有偏所估计的别⼈⼝袋每张钱的数学期望(平均值)= 10 ∗ 2/3 + 100 ∗ 1/3。

3.为何要⽤⽆偏估计?

因为现实⽣活中我不知道某个样本出现的概率啊,就像骰⼦,我不知道他是不是加过⽔银。

所以我们暂时按照每种情况出现概率⼀样来算。

 

GBDT原理深入刨析

想要理解GBDT的真正意义,那就必须理解GBDT中的Gradient Boosting(梯度提升Decision Tree分别是什么?

梯度概念复习

GDBT执行流程:

1 Decision TreeCART回归树

⾸先,GBDT使⽤的决策树是CART回归树,⽆论是处理回归问题还是⼆分类以及多分类,GBDT使⽤的决策树通通都是CART回归树。

  • 为什么不⽤CART分类树呢?
    • 因为GBDT每次迭代要拟合的是梯度值,是连续值所以要⽤回归树。

对于回归树算法来说最重要的是寻找最佳的划分点,那么回归树中的可划分点包含了所有特征的所有可取的值。

在分类树中最佳划分点的判别标准是熵或者基尼系数,都是⽤纯度来衡量的,但是在回归树中的样本标签是连续数值,所以再使⽤熵之类的指标不再合适,取而代之的是平方误差,它能很好的评判拟合程度。

1.1 回归树生成算法(复习)

参照上文《回归决策树》

2 Gradient Boosting: 拟合负梯度

梯度提升树(Grandient Boosting)是提升树(Boosting Tree)的⼀种改进算法,所以在讲梯度提升树之前先来说⼀下提升树。

先来个通俗理解:假如有个⼈30岁,我们⾸先⽤20岁去拟合,发现损失有10岁,这时我们⽤6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们⽤3岁拟合剩下的差距,差距就只有⼀岁了。如果我们的迭代轮数还没有完,可以继续迭代下⾯,每⼀轮迭代,拟合的岁数误差都会减⼩。最后将每次拟合的岁数加起来便是模型输出的结果。

提升树算法:

(1)初始化f0(x) = 0

(2)对m=1,2,...,M

  • (a)计算残差
  • (b)拟合残差rmi 学习⼀个回归树,得到hm(x)
  • (c)更新

(3)得到回归问题提升树

上⾯伪代码中的残差是什么?

在提升树算法中,

  • 假设我们前⼀轮迭代得到的强学习器是:
  • 损失函数是:
  • 我们本轮迭代的⽬标是找到⼀个弱学习器:ht(x)
  • 让本轮的损失最⼩化:
  • 当采⽤平⽅损失函数时:

  • 这⾥,是当前模型拟合数据的残差(residual)。
  • 所以,对于提升树来说只需要简单地拟合当前模型的残差。

回到我们上⾯讲的那个通俗易懂的例⼦中,第⼀次迭代的残差是10岁,第⼆ 次残差4岁,,,,,,

当损失函数是平⽅损失和指数损失函数时,梯度提升树每⼀步优化是很简单的,但是对于⼀般损失函数⽽⾔,往往每⼀步优化起来不那么容易。

针对这⼀问题,Friedman提出了梯度提升树算法,这是利⽤最速下降的近似⽅法,其关键是利⽤损失函数的负梯度作为提升树算法中的残差的近似值

那么负梯度⻓什么样呢?

  • 第t轮的第i个样本的损失函数的负梯度为:

  • 此时不同的损失函数将会得到不同的负梯度,如果选择平⽅损失:

  • 负梯度为:

此时我们发现GBDT的负梯度就是残差,所以说对于回归问题,我们要拟合的就是残差。

那么对于分类问题呢?

  • ⼆分类和多分类的损失函数都是logloss。

本⽂以回归问题为例进⾏讲解。

3 GBDT算法原理

上⾯两节分别将Decision Tree和Gradient Boosting介绍完了,下⾯将这两部分组合在⼀起就是我们的GBDT了。

GBDT算法:

  • (1)初始化弱学习器

  • (2)对m=1,2,...,M有:
    • (a)对每个样本i=1,2,...,N,计算负梯度,即残差

    • (b)将上步得到的残差作为样本新的真实值,并将数据(xi, rim),i = 1, 2, ..N作为下棵树的训练数据,得到⼀颗新的回归树fm(x)其对应的叶⼦节点区域为Rjm, j = 1, 2, ..., J。其中J为回归树t的叶⼦节点的个数。
    • (c)对叶⼦区域j=1,2,..J计算最佳拟合值

    • (d)更新强学习器

  • (3)得到最终学习器

 

4 实例介绍

4.1 数据介绍

根据如下数据,预测最后⼀个样本的身⾼。

编号 年龄 (岁) 体重(kg) 身高 (m)(标签值)
0 5 20 1.1
1 7 30 1.3
2 21 70 1.7
3 30 60 1.8
4 (要预测的) 25 65 ?

4.2 模型训练

4.2.1 设置参数:

  • 学习率:learning_rate=0.1
  • 迭代次数:n_trees=5
  • 树的深度:max_depth=3

4.2.2 开始训练

计算损失函数,求出第一个预测值:

思路:

1.初始化弱学习器:

损失函数为平⽅损失,因为平⽅损失函数是⼀个凸函数,直接求导:

 

令导数等于0,得到c。

                                              

具体实现:

所以初始化时,c取值为所有训练样本标签值的均值。c = (1.1 + 1.3 + 1.7 + 1.8)/4 = 1.475,此时得到初始学习器f0(x):

f 0(x) = c = 1.475

2.求解划分点

计算负梯度,根据上⽂损失函数为平⽅损失时,负梯度就是残差,再直⽩⼀点就是 y与上⼀轮得到的学习器f m-1的差值:

残差在下表列出:

编号 真实值 残差
0 1.1 1.475 -0.375
1 1.3 1.475 -0.175
2 1.7 1.475 0.225
3 1.8 1.475 0.325

重构目标值

此时将残差作为样本的目标值来训练弱学习器f 1(x),即下表数据

编号 年龄 (岁) 体重(kg) 标签值
0 5 20 -0.375
1 7 30 -0.175
2 21 70 0.225
3 30 60 0.325

 

接着,寻找回归树的最佳划分节点,遍历每个特征的每个可能取值。

从年龄特征的5开始,到体重特征的70结束,分别计算分裂后两组数据的平⽅损失(Square Error),

SE l 左节点平⽅损失,SE r 右节点平⽅损失,找到使平⽅损失和SE sum = SE l + SE r  最⼩的那个划分节点,即为最佳划分节点。

例如:以年龄21为划分节点,将⼩于21的样本划分为到左节点,⼤于等于21的样本划分为右节点。左节点包括x 0 , x 1,右节点包括样本x 2, x 3

注意!下面的的0.275是每个划分类的标签值的均值

SE l  = [−0.375 − (−0.275)] 2+ [−0.175 − (−0.275)] 2= 0.02            解释:-0.275=(-0.375-0.175)/2

SE r = [0.225 − 0.275] 2+ [0.325 − 0.275] 2= 0.005       解释:-0.275=(0.225+0.325)/2

SE sum = 0.025,

所有可能划分情况如下表所示:

划分点

⼩于划分点的样本

⼤于等于划分点的样本

SE l   SE r  SE sum
年龄 5 / 0,1,2,3 0 0.327 0.327
年龄 7 0 1,2,3 0 0.14 0.14
年龄 21 0,1 2,3 0.02 0.005 0.025
年龄 30 0,1,2 3 0.187 0 0.187
体重 20 / 0,1,2,3 0 0.327 0.327
体重 30 0 1,2,3 0 0.14 0.14
体重 60 0,1 2,3 0.02 0.005 0.025
体重 70 0,1,3 2 0.26 0 0.26

 

以上划分点是的总平⽅损失最⼩为0.025有两个划分点:年龄21和体重60,所以随机选⼀个作为划分点,这⾥我们选 21 现在我们的第⼀棵树⻓这个样⼦:

我们设置的参数中树的深度max_depth=3,现在树的深度只有2,需要再进⾏⼀次划分,这次划分要对左右两个节点分别进⾏划分:

对于左节点,只含有0,1两个样本,根据下表我们选择年龄7划分

划分点 小于划分点的样本 大于等于划分点的样本
年龄 5 / 0, 1 0 0.02 0.02
年龄 7 0 1 0 0 0
体重 20 / 0, 1 0 0.02 0.02
体重 30 0 1 0 0 0

对于右节点,只含有2,3两个样本,根据下表我们选择年龄30划分(也可以选体重70

划分点 小于划分点的样本 大于等于划分点的样本
年龄 21 / 2,3 0 0.005 0.005
年龄 30 2 3 0 0 0
体重 60 / 2,3 0 0.005 0.005
体重 70 3 2 0 0 0

现在我们的第⼀棵树⻓这个样⼦:

此时我们的树深度满⾜了设置,还需要做⼀件事情,给这每个叶⼦节点分别赋⼀个参数Υ,来拟合残差。

这⾥其实和上⾯初始化学习器是⼀个道理,平⽅损失,求导,令导数等于零,化简之后得到每个叶⼦节点的参数Υ,其实就是标签值的均值。这个地⽅的标签值不是原始的 y,⽽是本轮要拟合的标残差 y f (x).

根据上述划分结果,为了⽅便表示,规定从左到右为第1,2,3,4个叶⼦结点

此时的树⻓这个样⼦:

 

此时可更新强学习器,需要⽤到参数学习率:learning_rate=0.1,⽤lr 表示。

为什么要⽤学习率呢?这是Shrinkage的思想,如果每次都全部加上(学习率为1)很容易⼀步学到位导致过拟合。重复此步骤,直到 m>5 结束,最后⽣成5棵树。

结果中,0.9倍这个现象,和其学习率有关。这是因为数据简单每棵树⻓得⼀样,导致每⼀颗树的拟合效果⼀样,⽽每棵树都只学上⼀棵树残差的0.1倍,导致这颗树只能拟合剩余0.9了。

3.得到最后的强学习器

4.预测样本:

f0(x) = 1.475

  • 在f1(x)中,样本4的年龄为25,⼤于划分节点21岁,⼜⼩于30岁,所以被预测为0.2250;
  • 在f2(x)中,样本4的…此处省略…所以被预测为0.2025;
  • 在f3(x)中,样本4的…此处省略…所以被预测为0.1823;
  • 在f4(x)中,样本4的…此处省略…所以被预测为0.1640;
  • 在f5(x)中,样本4的…此处省略…所以被预测为0.1476.

最终预测结果:

f(x) = 1.475 + 0.1 ∗ (0.225 + 0.2025 + 0.1823 + 0.164 + 0.1476) = 1.56714

5 ⼩结

GBDT算法原理【知道】

  • (1)初始化弱学习器

  • (2)对m=1,2,...,M有:
    • (a)对每个样本i=1,2,...,N,计算负梯度,即残差

    • (b)将上步得到的残差作为样本新的真实值,并将数据(xi, rim),i = 1, 2, ..N作为下棵树的训练数据,得到⼀颗新的回归树fm(x)其对应的叶⼦节点区域为Rjm, j = 1, 2, ..., J。其中J为回归树t的叶⼦节点的个数。
    • (c)对叶⼦区域j=1,2,..J计算最佳拟合值

    • (d)更新强学习器

  • (3)得到最终学习器

 

posted @ 2025-06-17 21:17  指尖下的世界  阅读(67)  评论(0)    收藏  举报