GVKun编程网logo

xgb.train和xgb.XGBRegressor(或xgb.XGBClassifier)之间有什么区别?(xbar-r与xbar-s的区别)

16

本文的目的是介绍xgb.train和xgb.XGBRegressor的详细情况,特别关注或xgb.XGBClassifier之间有什么区别?的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,

本文的目的是介绍xgb.train和xgb.XGBRegressor的详细情况,特别关注或xgb.XGBClassifier之间有什么区别?的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解xgb.train和xgb.XGBRegressor的机会,同时也不会遗漏关于6.GBDT、随机森林(RF)、Xgboost、LightGBM、AttributeError:“ XGBClassifier”对象没有属性“ _le”、gbdt xgboost 贼难理解!、GBDT、XGboost原理介绍的知识。

本文目录一览:

xgb.train和xgb.XGBRegressor(或xgb.XGBClassifier)之间有什么区别?(xbar-r与xbar-s的区别)

xgb.train和xgb.XGBRegressor(或xgb.XGBClassifier)之间有什么区别?(xbar-r与xbar-s的区别)

我已经知道“xgboost.XGBRegressor是XGBoost的Scikit-Learn包装器界面”。

但是它们还有其他区别吗?

答案1

小编典典

xgboost.train 是用于通过梯度提升方法训练模型的低级API。

xgboost.XGBRegressorxgboost.XGBClassifier是包装器(它们称为 Scikit-Learn式包装器)
,它们准备DMatrix并传入相应的目标函数和参数。最后,fit调用简单地归结为:

self._Booster = train(params, dmatrix,                      self.n_estimators, evals=evals,                      early_stopping_rounds=early_stopping_rounds,                      evals_result=evals_result, obj=obj, feval=feval,                      verbose_eval=verbose)

这意味着, 一切都
可以用做XGBRegressor并且XGBClassifier是通过基本可行的xgboost.train功能。另一方面,显然不正确,例如,APIxgboost.train不支持某些有用的参数XGBModel。显着差异列表包括:

  • xgboost.train允许callbacks在每次迭代结束时设置应用。
  • xgboost.train允许通过xgb_model参数继续训练。
  • xgboost.train 不仅允许评估函数的最小化,而且还允许最大化。

6.GBDT、随机森林(RF)、Xgboost、LightGBM

6.GBDT、随机森林(RF)、Xgboost、LightGBM

GBDT、随机森林(RF)、Xgboost、LightGBM

1.CART树

损失函数参考上一章

算法流程:

Step1:对于数据集D,遍历所有特征,根据Gini(D,A)找到A,用A对D进行划分

Step2:重复步骤1,为每个节点找寻到最佳特征直到:1)节点样本数小于阈值2)Gini(D,A)小于阈值3)没有更多的特征值

2.随机森林(bagging)

初始化:决策树的个数n,每个决策树里每次分裂所选取的特征个数k,$k = {\log _2}n$

森林函数:$f(x) = \frac{1}{n}\sum\limits_i^n {{\varphi _i}(x)}$

算法流程:

Step1:从原始数据集中有放回的抽n次,每次m个样本

Step2:$k = {\log _2}n$,对每一组m个数据进行训练CART树,特征是从原始特征中随机选择k个

Setp3:每个树分裂下去,直到停止条件(参考CART树)

3.AdaBoost(Boosting

AdaBoost是boosting的想法,由一个弱学习器不断学习得到强学习器。AdaBoost主要增大了被分错样本的权重,改变的是样本的权重。

算法流程:

Input:训练数据集$T = \{ ({x_1},{y_1}),({x_2},{y_2}),...,({x_N},{y_N})\}$

Output: 最终的分类器$G(x)$

1.初始化样本权重${D_0} = ({w_{0,1}},{w_{0,2}},...,{w_{0,N}})$

2.对设置要训练的M棵树(学习器)

  • 使用${D_m}$的权重样本数据进行训练,得到一个分类器${G_m}(x)$
  • 根据${G_m}(x)$计算分类误差:${e_m} = \sum\limits_{i = 1}^N {{w_{mi}}} I({G_m}({x_i}) \ne {y_i})$
  • 计算${G_m}(x)$的系数:${\alpha _m} = \frac{1}{2}\log \frac{{1 - {e_m}}}{{{e_m}}}$
  • 更新训练样本的权重:

$$ \begin{array}{l} {D_m} = ({w_{m,1}},{w_{m,2}},...,{w_{m,N}})\\ {w_{m,i}} = \frac{{{w_{m - 1,i}}}}{{{z_m}}}\exp ( - {\alpha _m}{y_i}{G_m}({x_i})) \end{array} $$

  • 构建最终分类器的线性组合:

$$ G(x) = sign(\sum\limits_{m = 1}^M {{\alpha _m}{G_m}(x)} ) $$

其中权重有以下特点:

  • ${e_m}$越小,${\alpha _m}$越大
  • 分类错误的${w_{m,i}}$ > 分类正确的${w_{m,i}}$

4.GBDT(Gradient Boost Decision Tree)梯度提升树

GBDT是以回归树为基学习器的算法,采用Boosting思想。GBDT的核心在于:每一棵树学的都是之前所有树叠加后的残差。利用损失函数的负梯度在当前模型的值作为回归树的残差近似值。

算法流程:

Input:训练数据集$T = \{ ({x_1},{y_1}),({x_2},{y_2}),...,({x_N},{y_N})\}$

Output:回归树$\widehat f(x)$

1.初始化:${f_0}(x) = \mathop {\arg \min }\limits_c \sum\limits_{i = 1}^N {L({y_i},c)}$

2.对设置M棵树m=1,2,...,M:

  • 对i=1,2,...,N个样本,计算:${r_{mi}} = - {\left[ {\frac{{\partial L({y_i},f({x_i}))}}{{\partial f({x_i})}}} \right]_{f(x) = {f_{m - 1}}(x)}}$
  • 对${r_{mi}}$拟合一棵回归树,得到第m棵树的结点最优区域${R_{mj}},j = 1,2,...,J$。这个J是J个类别(分类树),叶子节点个数,可以理解为y的值个数(回归树)
  • 求解最优j区域(特征)的阈值,计算${C_{mj}} = \min \sum\limits_{{x_i} \in {R_{mj}}} {L({y_i},{f_{m - 1}}({x_i}) + c)}$
  • 更新${f_m}(x) = {f_{m - 1}}(x) + \sum\limits_{j = 1}^J {{C_{mj}}I(x \in {R_{mj}})}$

3.得到回归树:${f_m}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{C_{mj}}I(x \in {R_{mj}})} }$

这里需要提一点,如果设置树的深度为5,每次2分裂,那么J=10个叶子节点。有J个叶子节点就有J个判断条件

5.Xgboost

GBDT的升级版,从上面GBDT的算法流程中可以看出在负梯度中是一阶导数,并且在求解Cmj的时候是一个线性搜索,Xgboost把Rmj和Cmj合在一起求解,并且在损失函数中加入正则项

算法流程:

Input:训练数据集$T = \{ ({x_1},{y_1}),({x_2},{y_2}),...,({x_N},{y_N})\}$

Output:回归树$\widehat f(x)$

1.初始化:${f_0}(x) = \mathop {\arg \min }\limits_c \sum\limits_{i = 1}^N {L({y_i},c)}$

2.对设置M棵树m=1,2,...,M:

  • 对i=1,2,...,N个样本,计算一阶导数合${G_t} = \sum\limits_{i = 1}^N {{g_{ti}}} $以及二阶导数合${H_t} = \sum\limits_{i = 1}^N {{h_{ti}}} $,其中:

$$ \begin{array}{l} {g_{ti}} = \frac{{\partial L({y_i},{f_{t - 1}}({x_i}))}}{{\partial {f_{t - 1}}({x_i})}}, {h_{ti}} = \frac{{{\partial ^2}L({y_i},{f_{t - 1}}({x_i}))}}{{\partial {f_{t - 1}}^2({x_i})}} \end{array} $$

  • 求解最优j=1,2,...,J区域(特征)以及区域j阈值,根据${G_{tj}} = \sum\limits_{xi \in {R_{tj}}}^{} {{g_{ti}}} ,{H_{tj}} = \sum\limits_{xi \in {R_{tj}}}^{} {{h_{ti}}}$,求解叶子节点最优解:${\omega _{tj}} = - \frac{{{G_{tj}}}}{{{H_{tj}} + \lambda }}$,这个类似于GBDT的区域求解。
  • 对于k=1,2,...,K个特征,每个k特征线性划分不同阈值进行线性搜索。初始化${\rm{score = 0}},{G_L} = 0,{G_R} = 0$,对每个i样本,求左右树的一阶导数合二阶导数:

$$ \begin{array}{l} {G_L} = {G_L} + {g_{ti}},{G_R} = G - {G_L}\\ {H_L} = {H_L} + {h_{ti}},{H_R} = H - {H_L} \end{array} $$

  • 计算$score = \max (score,\frac{1}{2}(\frac{{G_L^2}}{{{H_L} + \lambda }} + \frac{{G_R^2}}{{{H_R} + \lambda }} - \frac{{{{({G_L} + {G_R})}^2}}}{{{H_L} + {H_R} + \lambda }}) - \gamma )$

3.基于最大的score进行分裂
4.得到回归树:${f_m}(x) = \sum\limits_{m = 1}^M {\sum\limits_{j = 1}^J {{C_{mj}}I(x \in {R_{mj}})} }$

参考https://ranmaosong.github.io/...

6.LightGBM

具体算法参见https://zhuanlan.zhihu.com/p/...
优化点:

  • 特征对不同取值进行直方图分bin
  • 带深度限制的叶子节点分裂,Xgboost在分裂叶子节点时候是对同一层的所有叶子节点无差别分裂,权重相同。这个是不合适的,因为每个叶子节点的分裂增益各不相同。ligtgbm对每一层只找到分裂增益最大的一个叶子节点进行分裂。
  • 对每个样本进行权重加成
  • 稀疏特征合并。

这里比较下GBDT合Xgboost的10个区别:

  • GBDT是机器学习算法,Xgboost是工程实现
  • Xgboost加入了正则项来防止过拟合
  • Xgboost采用一阶和二阶泰勒展开损失函数
  • Xgboost支持多种基学习器
  • Xgboost对缺失值进行了处理
  • Xgboost加入了Shrinkage(缩减),每棵树乘上一个学习率,这样的话可以多学习几轮。
  • Xgboost支持叶子节点分裂的并行操作。
  • Xgboost采用贪心算法,也就是对每次分裂都是最大增益,而不是一个总的最小损失函数
  • Xgboost对特征事先排序了
  • Xgboost支持列抽样,参考随机森林的特征抽样

AttributeError:“ XGBClassifier”对象没有属性“ _le”

AttributeError:“ XGBClassifier”对象没有属性“ _le”

如何解决AttributeError:“ XGBClassifier”对象没有属性“ _le”?

我正在尝试将我的xgboost模型对象(0.60版本)适合OOT数据,但始终会出错。我正在使用以下代码行:

fname = "xgb"  
if isinstance(xgb,XGBClassifier):
 regressor = XGBClassifier()
 r = pickle.load(open(fname,"rb" ))
 print(r)
 regressor._Booster = r._Booster
 regressor.set_params(**r.get_xgb_params())

y_predict = regressor.predict(oot)

错误:

AttributeError: ''XGBClassifier'' object has no attribute ''_le''

我还尝试使用其他方式对OOT数据评分:

scored = scored_data.predict(oot)

然后我遇到错误(我创建了类似的环境复制模型dev)

class_probs = self.booster().predict(test_dmatrix,output_margin=output_margin,ntree_limit=ntree_limit)

TypeError: ''str'' object is not callable

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

gbdt xgboost 贼难理解!

gbdt xgboost 贼难理解!

https://www.zybuluo.com/yxd/note/611571

https://zhuanlan.zhihu.com/p/29765582

gbdt 在看统计学习方法的时候 理解很吃力。 参考了以上两篇文章,作者写的非常好。

冒昧转载过来。

 

机器学习 - 一文理解 GBDT 的原理 - 20171001

 

现在网上介绍 gbdt 算法的文章并不算少,但总体看下来,千篇一律的多,能直达精髓的少,有条理性的就更稀少了。我希望通过此篇文章,能抽丝剥茧般的向初学者介绍清楚这个算法的原理所在。如果仍不清楚可以在文后留言。

1、如何在不改变原有模型的结构上提升模型的拟合能力

假设现在你有样本集 (x_{1},y_{1}),(x_{2},y_{2}),...(x_{n},y_{n}) ,然后你用一个模型,如 F(x) 去拟合这些数据,使得这批样本的平方损失函数(即 \frac{1}{2}\sum_{0}^{n}{}(y_{i}-F(x_{i}))^{2} )最小。但是你发现虽然模型的拟合效果很好,但仍然有一些差距,比如预测值 F(x_{1}) =0.8,而真实值 y_{1} =0.9, F(x_{2})=1.4, y_{2} =1.3 等等。另外你不允许更改原来模型 F(x) 的参数,那么你有什么办法进一步来提高模型的拟合能力呢。

既然不能更改原来模型的参数,那么意味着必须在原来模型的基础之上做改善,那么直观的做法就是建立一个新的模型 f(x) 来拟合 F(x) 未完全拟合真实样本的残差,即 y-F(X) 。所以对于每个样本来说,拟合的样本集就变成了: (x_{1},y_{1}-F(x_{1})),(x_{2},y_{2}-F(x_{2})),...(x_{n},y_{n}-F(x_{n})) .

2、基于残差的 gbdt

在第一部分, y_{i}-F(x_{i}) 被称为残差,这一部分也就是前一模型( F(x_{i}) )未能完全拟合的部分,所以交给新的模型来完成。

我们知道 gbdt 的全称是 Gradient Boosting Decision Tree,其中 gradient 被称为梯度,更一般的理解,可以认为是一阶导,那么这里的残差与梯度是什么关系呢。在第一部分,我们提到了一个叫做平方损失函数的东西,具体形式可以写成 \frac{1}{2}\sum_{0}^{n}{}(y_{i}-F(x_{i}))^{2} ,熟悉其他算法的原理应该知道,这个损失函数主要针对回归类型的问题,分类则是用熵值类的损失函数。具体到平方损失函数的式子,你可能已经发现它的一阶导其实就是残差的形式,所以基于残差的 gbdt 是一种特殊的 gbdt 模型,它的损失函数是平方损失函数,常用来处理回归类的问题。具体形式可以如下表示:

损失函数:L(y,F(x)) = \frac{1}{2}(y-F(X))^{2}

所以我们想最小化J = \frac{1}{2}\sum_{0}^{n}{}(y_{i}-F(x_{i}))^{2}

损失函数的一阶导:

正好残差就是负梯度:

3、为什么基于残差的 gbdt 不是一个好的选择

基于残差的 gbdt 在解决回归问题上不算是一个好的选择,一个比较明显的缺点就是对异常值过于敏感。我们来看一个例子:

很明显后续的模型会对第 4 个值关注过多,这不是一种好的现象,所以一般回归类的损失函数会用绝对损失或者 huber 损失函数来代替平方损失函数:

4、Boosting 的加法模型

如前面所述,gbdt 模型可以认为是是由 k 个基模型组成的一个加法运算式:

\hat{y}_i=\sum_{k=1}^K f_k(x_i), f_k \in F \tag 0

其中 F 是指所有基模型组成的函数空间。

那么一般化的损失函数是预测值 \hat{y} 与 真实值y 之间的关系,如我们前面的平方损失函数,那么对于 n 个样本来说,则可以写成:

L=\sum_{i=1}^n l(y_i, \hat{y}_i)

更一般的,我们知道一个好的模型,在偏差和方差上有一个较好的平衡,而算法的损失函数正是代表了模型的偏差面,最小化损失函数,就相当于最小化模型的偏差,但同时我们也需要兼顾模型的方差,所以目标函数还包括抑制模型复杂度的正则项,因此目标函数可以写成:

Obj=\sum_{i=1}^n l(y_i, \hat{y}_i) + \sum_{k=1}^K \Omega(f_k)

其中 \Omega 代表了基模型的复杂度,若基模型是树模型,则树的深度、叶子节点数等指标可以反应树的复杂程度。

对于 Boosting 来说,它采用的是前向优化算法,即从前往后,逐渐建立基模型来优化逼近目标函数,具体过程如下:

\begin{split} \hat{y}_i^0 &= 0 \\ \hat{y}_i^1 &= f_1(x_i) = \hat{y}_i^0 + f_1(x_i) \\ \hat{y}_i^2 &= f_1(x_i) + f_2(x_i) = \hat{y}_i^1 + f_2(x_i) \\ & \cdots \\ \hat{y}_i^t &= \sum_{k=1}^t f_k(x_i) = \hat{y}_i^{t-1} + f_t(x_i) \\ \end{split}

那么,在每一步,如何学习一个新的模型呢,答案的关键还是在于 gbdt 的目标函数上,即新模型的加入总是以优化目标函数为目的的。

我们以第 t 步的模型拟合为例,在这一步,模型对第 i 个样本 x_{i} 的预测为:

\hat{y}_i^t= \hat{y}_i^{t-1} + f_t(x_i)

其中 f_t(x_i) 就是我们这次需要加入的新模型,即需要拟合的模型,此时,目标函数就可以写成:

\begin{split} Obj^{(t)} &= \sum_{i=1}^nl(y_i, \hat{y}_i^t) + \sum_{i=i}^t \Omega(f_i) \\ &= \sum_{i=1}^n l\left(y_i, \hat{y}_i^{t-1} + f_t(x_i) \right) + \Omega(f_t) + constant \end{split}\tag{1}

即此时最优化目标函数,就相当于求得了 f_t(x_i) 。

5、什么是 gbdt 的目标函数

我们知道泰勒公式中,若 \Delta x 很小时,我们只保留二阶导是合理的(gbdt 是一阶导,xgboost 是二阶导,我们以二阶导为例,一阶导可以自己去推,因为更简单),即:

f(x+\Delta x) \approx f(x) + f''(x)\Delta x + \frac12 f''''(x)\Delta x^2 \tag 2

那么在等式(1)中,我们把 \hat{y}_i^{t-1} 看成是等式(2)中的 x, f_t(x_i) 看成是 \Delta x ,因此等式(1)可以写成:

Obj^{(t)} = \sum_{i=1}^n \left[ l(y_i, \hat{y}_i^{t-1}) + g_if_t(x_i) + \frac12h_if_t^2(x_i) \right] + \Omega(f_t) + constant \tag 3

其中 g_{i} 为损失函数的一阶导, h_{i} 为损失函数的二阶导,注意这里的导是对 \hat{y}_i^{t-1} 求导。我们以 平方损失函数为例\sum_{i=1}^n \left(y_i - (\hat{y}_i^{t-1} + f_t(x_i)) \right)^2 ,则 g_i=\partial_{\hat{y}^{t-1}}(\hat{y}^{t-1} - y_i)^2 = 2(\hat{y}^{t-1} - y_i), h_i=\partial_{\hat{y}^{t-1}}^2(\hat{y}^{t-1} - y_i)^2 = 2 。

由于在第 t 步 \hat{y}_i^{t-1} 其实是一个已知的值,所以  l(y_i, \hat{y}_i^{t-1}) 是一个常数,其对函数优化不会产生影响,因此,等式(3)可以写成:

Obj^{(t)} \approx \sum_{i=1}^n \left[ g_if_t(x_i) + \frac12h_if_t^2(x_i) \right] + \Omega(f_t) \tag 4

所以我么只要求出每一步损失函数的一阶和二阶导的值(由于前一步的 \hat{y}^{t-1} 是已知的,所以这两个值就是常数)代入等式 4,然后最优化目标函数,就可以得到每一步的 f(x) ,最后根据加法模型得到一个整体模型。

 

6、如何用决策树来表示上一步的目标函数

假设我们 boosting 的基模型用决策树来实现,则一颗生成好的决策树,即结构确定,也就是说树的叶子结点其实是确定了的。假设这棵树的叶子结点有 T 片叶子,而每片叶子对应的值 w \in R^T 。熟悉决策树的同学应该清楚,每一片叶子结点中样本的预测值都会是一样的,在分类问题中,是某一类,在回归问题中,是某一个值(在 gbdt 中都是回归树,即分类问题转化成对概率的回归了),那么肯定存在这样一个函数 q:R^d \to \{1,2,\cdots,T\} ,即将 f_{t}(x) 中的每个样本映射到每一个叶子结点上,当然 f_{t}(x) 和 q 我们都是不知道的,但我们也不关心,这里只是说明一下决策树表达数据结构的方法是怎么样的,不理解也没有问题。

那么 f_{t}(x) 就可以转成 w_{q(x)} ,这里的 q(x) 代表了每个样本在哪个叶子结点上,而 w_{q} 则代表了哪个叶子结点取什么 w 值,所以 w_{q(x)} 就代表了每个样本的取值 w (即预测值)。

如果决策树的复杂度可以由正则项来定义 \Omega(f_t)=\gamma T + \frac12 \lambda \sum_{j=1}^T w_j^2 ,即决策树模型的复杂度由生成的树的叶子节点数量和叶子节点对应的值向量的 L2 范数决定。

 

我们假设 I_j=\{ i \vert q(x_i)=j \} 为第 j 个叶子节点的样本集合,则等式 4 根据上面的一些变换可以写成:

\begin{split} Obj^{(t)} &\approx \sum_{i=1}^n \left[ g_if_t(x_i) + \frac12h_if_t^2(x_i) \right] + \Omega(f_t) \\ &= \sum_{i=1}^n \left[ g_iw_{q(x_i)} + \frac12h_iw_{q(x_i)}^2 \right] + \gamma T + \frac12 \lambda \sum_{j=1}^T w_j^2 \\ &= \sum_{j=1}^T \left[(\sum_{i \in I_j}g_i)w_j + \frac12(\sum_{i \in I_j}h_i + \lambda)w_j^2 \right] + \gamma T \end{split}\tag 5

即我们之前样本的集合,现在都改写成叶子结点的集合,由于一个叶子结点有多个样本存在,因此才有了 \sum_{i \in I_j}g_i 和 \sum_{i \in I_j}h_i 这两项。

定义 G_j=\sum_{i \in I_j}g_i , H_j=\sum_{i \in I_j}h_i ,则等式 5 可以写成:

Obj^{(t)} = \sum_{j=1}^T \left[G_jw_j + \frac12(H_j + \lambda)w_j^2 \right] + \gamma T

如果树的结构是固定的,即 q 是确定的,或者说我们已经知道了每个叶子结点有哪些样本,所以 G_j 和 H_j 是确定的,但 w 不确定( w 其实就是我们需要预测的值),那么令目标函数一阶导为 0,则可以求得叶子结点 j 对应的值:

w_j^*=-\frac{G_j}{H_j+\lambda} \tag 6

目标函数的值可以化简为:

Obj = -\frac12 \sum_{j=1}^T \frac{G_j^2}{H_j+\lambda} + \gamma T \tag 7

 

7、如何最优化目标函数

那么对于单棵决策树,一种理想的优化状态就是枚举所有可能的树结构,因此过程如下:

a、首先枚举所有可能的树结构,即 q ;

b、计算每种树结构下的目标函数值,即等式 7 的值;

c、取目标函数最小(大)值为最佳的数结构,根据等式 6 求得每个叶子节点的 w 取值,即样本的预测值。

但上面的方法肯定是不可行的,因为树的结构千千万,所以一般用贪心策略来优化:

a、从深度为 0 的树开始,对每个叶节点枚举所有的可用特征

b、 针对每个特征,把属于该节点的训练样本根据该特征值升序排列,通过线性扫描的方式来决定该特征的最佳分裂点,并记录该特征的最大收益(采用最佳分裂点时的收益)

c、 选择收益最大的特征作为分裂特征,用该特征的最佳分裂点作为分裂位置,把该节点生长出左右两个新的叶节点,并为每个新节点关联对应的样本集

d、回到第 1 步,递归执行到满足特定条件为止

那么如何计算上面的收益呢,很简单,仍然紧扣目标函数就可以了。假设我们在某一节点上二分裂成两个节点,分别是左(L)右(R),则分列前的目标函数是 -\frac12 [\frac{(G_L+G_R)^2}{H_L+H_R+\lambda}] + \gamma  ,分裂后则是 -\frac12 [ \frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda}] +2\gamma ,则对于目标函数来说,分裂后的收益是(这里假设是最小化目标函数,所以用分裂前 - 分裂后):

Gain=\frac12 \left[ \frac{G_L^2}{H_L+\lambda} + \frac{G_R^2}{H_R+\lambda} - \frac{(G_L+G_R)^2}{H_L+H_R+\lambda}\right] - \gamma \tag 8

等式 8 计算出来的收益,也是作为变量重要度输出的重要依据。

所以 gbdt 的算法可以总结为:

a、算法在拟合的每一步都新生成一颗决策树;

b、在拟合这棵树之前,需要计算损失函数在每个样本上的一阶导和二阶导,即 g_{i} 和 h_{i} ;

c、通过上面的贪心策略生成一颗树,计算每个叶子结点的的 G_{j} 和 H_{j} ,利用等式 6 计算预测值 w ;

d、把新生成的决策树 f_t(x) 加入 \hat{y}_i^t = \hat{y}_i^{t-1} + \epsilon f_t(x_i) ,其中 \epsilon 为学习率,主要为了抑制模型的过拟合。

GBDT、XGboost原理介绍

GBDT、XGboost原理介绍

决策树

  • 决策树是一种基本的分类和回归方法。决策树模型呈树形结构,可以认为是if-else形式的判断集合。其主要的优点有:可读性好;分类速度快。
  • 决策树由节点和有向边组成,节点的类型有:内部节点——表示一个特征及其划分值;叶节点——类别或输出值。当使用决策树进行分类或者回归预测的时候,只需递归地按照内部节点的特征及划分值找到对应的叶节点即可,叶节点的类别或者值即为输出。

本文并不打算介绍分类决策树(大家可自行查询和学习ID3,C4.5,Random Forest等常用的基础决策树的原理,以及决策树的裁剪),而主要是为了介绍GBDT及XGBoost的原理。在介绍GBDT和xgboost之前,我们先介绍一下CART。

后文的标志:

  • 训练集: D={(x1,y1),(x2,y2),...,(xn,yn)},其中xi是m维的向量,yi是第i个训练样本的标准结果。(如果yi的取值是离散的,则是分类问题;如果yi的取值范围是连续的,则是回归问题)。本文中的yi为离散取值。

CART

分类和回归树(classification and regression tree, CART)是Breiman等人在1984提出的决策树学习方法。CART假设决策树是二叉树,内部节点表示的是对数据根据某个特征的某个值得划分,特征小于或等于该划分值得数据分配在该内部节点的做节点,大于划分值的数据则被划分到右节点。

那么,我们要怎样构建CART呢?决策树的构建问题主要有两点:内部节点选取哪个特征的哪个值作为划分特征?

首先要明确的是,我们的划分目的是使得划分后的到的数据相较于划分前更为纯粹(使得划分后的数据的不确定性更小),或者使得误差(损失值)更小。一般,我们对于不确定性的度量方法有信息熵(使用信息增益最大的划分方法作为划分依据)、基尼指数等,对于损失值可以采用平方损失函数等。对于回归分析,本文使用平方损失函数作为划分依据和损失函数。

算法流程

D={(x1,y1),(x2,y2),...,(xn,yn)},其中xi是k维的向量,yi是第i个训练样本的标准结果。训练过程——从根节点开始,递归得对每一节点进行一下操作:

  1. 设节点的数据集合为D,根据每个特征j的每个可能的取值(划分值)s,将数据划分为两个集合节点R1、R2,节点内数据样例的平均值c1,c2作为节点值(或者按比例使用加权值作为节点值)。计算划分后的损失:图片描述
  2. 选取划分损失最小的特征及其对应的划分值作为该节点的划分方式。
  3. 对两个子节点R1,R2,递归进行步骤1、2的处理直至满足停止条件(节点的数据样例个数为1;样例个数不为1,但是y相同;深度超过d等)。如果满足停止条件,则叶子节点内数据样例的平均值作为节点值(或者使用加权值作为节点值)。

至此,一颗CART就训练完成了。

提升决策树BDT

提升树(Boosting Decision Tree)是迭代多棵回归树来共同决策。当采用平方误差损失函数时,每一棵回归树学习的是之前所有树的结论和残差,拟合得到一个当前的残差回归树,一般,残差的意义如公式:残差 = 真实值 - 预测值 。提升树即是整个迭代过程生成的回归树的累加。提升树模型可以表示为决策树的加法模型:
图片描述

其中T(x;Θm)表示决策树;Θm为决策树的参数;M为树的个数。

算法流程:

D1=训练集D
// m为回归树数量(自定义),m越大表示越精确,同时也意味着可能过拟合
for i range m:
  Ti=根据Di使用训练出的一棵CART
  使用Ti对Di进行预测,rj=Ti对Di第j个样例的预测结果,并获取每个训练样本的残差yj'', 其中yj''=yj-rj
  Di+1={(x1,y1''),(x2,y2''),...,(xn,yn'')}

// 最后的模型为:
f(x)=T1+T2+...+Tm

梯度提升决策树GBDT

GBDT(Gradient Boosting Decision Tree)是一种迭代的决策树算法,又叫 MART(Multiple Additive Regression Tree),它通过构造一组弱的学习器(树),并把多颗决策树的结果累加起来作为最终的预测输出。该算法将决策树与集成思想进行了有效的结合。

我们需要知道的是,度量任何一个模型最重要的就是这个模型的损失函数。我们训练的目标就是使得损失函数L最小化。图片描述

当损失函数是平方损失和指数损失时,每一步优化是很简单的。但对一般损失函数而言,往往每一步优化没那么容易,如绝对值损失函数和Huber损失函数。常见的损失函数及其梯度如下表所示:图片描述

如何使得损失函数最小化?调整参数,使得损失沿着梯度方向下降!(不懂的话要重学数学分析。。。)

对于损失函数为平方损失函数的,我们可以使用的是yj-Ti对xj的预测结果作为残差。那么对于其他类型的损失函数我们应该使用什么作为残差以达到最好的效果呢呢?针对这一问题,Freidman(机器学习界的大佬)提出了梯度提升算法:利用最速下降的近似方法,即利用损失函数的负梯度在当前模型的值。图片描述

如果我们对提升树的损失函数求偏导,就可以发现,偏导是等于残差的~,见上上图。(因为上文的残差是损失函数梯度的一个特例,对应的损失函数为平方损失函数)。因此,对于不同的损失函数,我们可以使用损失函数的偏导作为我们的残差。

这就是梯度提升决策树了。

XGBoost

XGBoost的全称为eXtreme Gradient Boosting,是GBDT的一种高效实现,XGBoost中的基学习器除了可以是CART(gbtree)也可以是线性分类器(gblinear)。

  • 和GBDT不同,xgboost给损失函数增加了正则化项(L1或L2正则化项,视学习目标不同而取不同正则化参数。)
  • 有些损失函数是难以计算导数的,鉴于这种情况,xgboost使用损失函数的二阶泰勒展开作为损失函数的拟合
  • GBDT的节点分裂方式是遍历所有特征的所有可能划分,再选取最优者分裂。xgboost使用分位点及分位数法,近似地计算,有效降低计算量

参考:

  • GBDT
  • xgboost的数学模型、分位点及分位数法

推荐:

  • 《统计学习方法》——李航
  • 西瓜书——周志华

我们今天的关于xgb.train和xgb.XGBRegressor或xgb.XGBClassifier之间有什么区别?的分享就到这里,谢谢您的阅读,如果想了解更多关于6.GBDT、随机森林(RF)、Xgboost、LightGBM、AttributeError:“ XGBClassifier”对象没有属性“ _le”、gbdt xgboost 贼难理解!、GBDT、XGboost原理介绍的相关信息,可以在本站进行搜索。

本文标签: