gbdt算法_GBDT算法详解与代码实现

gbdt算法_GBDT算法详解与代码实现_第1张图片

1, 远观GBDT

GBDT算法也是有很多决策树(CART)集成而来,但与随机森林不同,GBDT生成的决策树之间有依赖关系,GBDT算法用到的是一种boosting策略,由弱学习器组合而成强学习器。

在GBDT中,每一轮弱学习器的得出都与已经得到的模型(已得到的弱学习器的组合)有关,怎么有关法?提到的弱学习器的组合是怎么做的?这是我们要学习的主要问题。先来大致讲述一下

  1. GBDT在当前轮的弱学习器中拟合损失函数的负梯度值在已经得到的模型的值,这与之前的机器学习算法不同,不再拟合真实值,而是拟合梯度值。
  2. 组合的方式就是简单直接的加法模型或者加入一个学习率之后在相加(防过拟合),有没有感觉进入了求损失函数最小用的梯度下降算法,我觉得就是这种算法。

具体怎么做和损失函数的设定问题我们下面详细讲解

2, 理论部分

样本
(自变量)对应的真实值,也就是我们要拟合的目标。

个弱学习期

个弱学习器的组合

损失函数的形式有多种,回归与分类所用的损失函数也不同,这篇文章我们先讲回归任务。

回归任务

选择的损失函数为

损失函数在已训练模型(前

个弱学习器的组合
)的负梯度值为

算法过程

  • 初始化第1个弱分类器
  • 第二个弱分类器的拟合值就为损失函数负梯度在已有模型(第一轮弱分类器)的值:

为训练数据拟合一条回归树(CART)作为第
个弱学习器
,每个

叶子结点的值取为此叶子结点所有样本值

的均值。为何取均值?本节最后我做个推导。
  • ....
  • 个弱学习器的拟合值为:
    ,
    ,以
    为训练数据得到第
    个决策树
    ,计算叶子节点的值。
  • 为我们最终得到的强学习器。

总结GBDT的思路:每一轮用一个回归树来拟合一个负梯度值。拟合完一颗树之后,需要计算叶子节点的值。最终预测结果其实就是每一颗树的预测结果相加,所以整个过程就是如此简单。

叶子结点取值的推导:(个人理解)

在某一轮弱学习器的学习中,损失函数可以写成

为叶子结点的个数,
为第
个叶子节点上的样本个数,
为第
个叶子节点的取值。

我们要找到最优的

使得损失函数最小,想到求导等于
,得到最优的值。

取值为零,得到

分类任务

分类任务也是建立回归树,原因嘛,因为要使用梯度下降算法,得到的连续型数值,个人看法而已。过程与回归任务的GBDT一样,不同之处在于损失函数不同,引起的负梯度形式不同,叶子结点计算方式不同。

选择的损失函数为逻辑损失:

其中

,因此第
个弱学习器的拟合值为损失函数的负梯度在已得出模型上的值

  • 初始化第1个弱分类器
    .
  • 第二个弱分类器的拟合值就为损失函数负梯度在已有模型(第一轮弱分类器)的值:

为训练数据拟合一条回归树(CART)作为第
个弱学习器
,每个

叶子结点的值取为:

,其中,
代表第

叶子。

  • ...
  • 个弱学习器的拟合值为:
    ,
    ,以
    为训练数据得到第
    个决策树
    ,计算叶子节点的值。
  • 为我们最终得到的强学习器,即样本
    为正样本的概率。

总结:与回归任务是不是过程已一致啊?有没有感觉被我的总结给忽悠了。嘻嘻

代码实现

我们直接调用函数来做一个分类任务

#先导入我们需要的库
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split#用于划分测试集与训练集

from sklearn.datasets import load_iris #使用sklearn库中的iris数据集
data = load_iris()
X = data.data #特征
Y=data.target #类标

X = X[0:100,:]
Y=Y[0:100] #我们做个二分类,iris本来是三个类,前100 个包括两个类
X_train,X_test,Y_train,Y_test=train_test_split(X,Y,
                                               test_size=0.2,random_state=0)#数据划分

clas = GradientBoostingClassifier(random_state=2020)#我们用的默认参数,如果数据比较复杂,需要调参
clas.fit(X_train,Y_train)#训练模型
clas.predict(X_train)#预测训练集
clas.predict(X_test)#预测测试集
print("训练集准确率:%s"%clas.score(X_train,Y_train)) #输出测试集准确度
print("测试集准确率:%s"%clas.score(X_test,Y_test))   #输出测试集准确度

训练集准确率:1.0
测试集准确率:1.0

关于模型参数问题,可参考http://www.itongji.cn/detail?type=1124

你可能感兴趣的:(gbdt算法)