集成学习(三) 提升学习 adaboost、gbdt、xgboost

原文链接: https://www.cnblogs.com/pinard/p/6140514.html

1、什么是梯度提升
假定当前已经得到了m-1颗决策树,能否通过现有样本对第m颗决策树产生影响呢?答案是可以的
在这里插入图片描述
一、Boosting与Adaboost
在随机森林的构建过程中,由于各棵树之间是没有关系的,相对独立的;在构建 的过程中,构建第m棵子树的时候,不会考虑前面的m-1棵树。
如果在构建第m棵子树的时候,考虑到前m-1棵子树的结果,会不会对最终结果产生有益 的影响? 各个决策树组成随机森林后,在形成最终结果的时候能不能给定一种既定的决策顺序呢? (也就是那颗子树先进行决策、那颗子树后进行决策)
提升学习(Boosting)是一种机器学习技术,可以用于回归和分类的问题,它每一步产生弱预测模型(如决策树),并加权累加到总模型中;如果每一步的弱预 测模型的生成都是依据损失函数的梯度方式的,那么就称为梯度提升(Gradient boosting);
提升技术的意义:如果一个问题存在弱预测模型,那么可以通过提升技术的办法 得到一个强预测模型;
常见的模型有: Adaboost Gradient Boosting(GBT/GBDT/GBRT)
boosting的学习思路如图所示:
在这里插入图片描述
1、AdaBoost
1、Adaboost分类树(用于分类)
算法原理:
Adaptive Boosting是一种迭代算法。每轮迭代中会在训练集上产生一个新的学 习器,然后使用该学习器对所有样本进行预测,以评估每个样本的重要性 (Informative)。换句话来讲就是,算法会为每个样本赋予一个权重,每次用训练 好的学习器标注/预测各个样本,如果某个样本点被预测的越正确,则将其权重 降低;否则提高样本的权重。权重越高的样本在下一个迭代训练中所占的比重就 越大,也就是说越难区分的样本在训练过程中会变得越重要;
整个迭代过程直到错误率足够小或者达到一定的迭代次数为止。
(1)算法介绍
在这里插入图片描述
注:这里基于每个分错的样本都给与一个权重,并且经过迭代,分错的样本的权重越大,分对的样本权重概率过小,Gm(x)的选择是基于误差率最小的原则
在这里插入图片描述
注:①关于am:
在这里插入图片描述
这里可以看出em越接近于0.5,am越小
D m = ( w m i ) D_m=(w_{mi}) ,每一轮迭代都会使,错误样本的权值扩大,即更加重视错误的样本。
在这里插入图片描述
当em>0.5:
在这里插入图片描述

③adaboost会建立m个模型,每个模型的都是基于上面的模型进行改进的,最后基于这m个模型的权重进行这个样本的判断。

补充:sign函数:
在这里插入图片描述
在这里插入图片描述
这里的损失函数是错误率的意思,I()函数代表,当括号中这个值为True时返回1,False时返回0,所以当分类器预测错误时返回1,正确返回0,得出的就为错误率。
例子:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个sign函数即, f 1 ( x ) f_1(x) >0 则取值为1,<0取值为-1,所以
在这里插入图片描述
从分类结果可以看出,分错的样本权重更大一些,分对的样本权重更小一点,这样计算的分类误差率em会不断变小
下面计算下一步的v的取值:
在这里插入图片描述
所以v等于8.5时分类的误差率最小。

计算代码:
y_true=[1,1,1,-1,-1,-1,1,1,1,-1]
w_i=[0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715]
#w_i=[0.1]*10
y_test=[-1]*10
for i in range(10):
    y_test[i]=1
    arr=[]
    for j in range(10):
        y_pre_tru=y_true[j]*y_test[j]
        if y_pre_tru==-1:
            y_pre_tru=1
        else:
            y_pre_tru=0            
        arr.append(w_i[j]*y_pre_tru)
    print(i)
    print(round(sum(arr),4))
    print(y_test)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
G(x)前面的系数相当于对这个弱分类器进行投票。

adaboost常见定理:
定理一:
在这里插入图片描述
现在先口头理解一下:上式左边一个不等式,右边一个等式;不等式的左边仔细一看,就是当前最终分类器 G(x) 对训练样本的误分类率。我们将上面的式子记作0式
在这里插入图片描述
可以看出m为弱分类器的个数,N为样本个数
在这里插入图片描述
在这里插入图片描述
定理2:
定理二(二类分类问题AdaBoost的训练误差界):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
定理二表明,adaboost的训练误差是以指数形式下降的

③Adaboost -sklearn库python的实现
scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个,从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。
当我们对Adaboost调参时,主要要对两部分内容进行调参,第一部分是对我们的Adaboost的框架进行调参, 第二部分是对我们选择的弱分类器进行调参。两者相辅相成。下面就对Adaboost的两个类:AdaBoostClassifier和AdaBoostRegressor从这两部分做一个介绍。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:一般构建器的调节主要是:弱分类类型(cart决策树还是cart回归树)、弱分类器个数(设置最大弱分类器个数)、学习率(每次对新学习器的权重),这些参数的调节可以通过模型检验的AUC曲线与混淆矩阵的得分来调节
<2> 弱分类器参数的调节

  1. 划分时考虑的最大特征数max_features: 可以使用很多种类型的值,默认是"None",意味着划分时考虑所有的特征数;如果是"log2"意味着划分时最多考虑log2N个特征;如果是"sqrt"或者"auto"意味着划分时最多考虑√N个特征。如果是整数,代表考虑的特征绝对数。如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数。其中N为样本总特征数。一般来说,如果样本特征数不多,比如小于50,我们用默认的"None"就可以了,如果特征数非常多,我们可以灵活使用刚才描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

  2. 决策树最大深max_depth: 默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。

  3. 内部节点再划分所需最小样本数min_samples_split: 这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。 默认是2.如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

  4. 叶子节点最少样本数min_samples_leaf: 这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

5)叶子节点最小的样本权重和min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

  1. 最大叶子节点数max_leaf_nodes: 通过限制最大叶子节点数,可以防止过拟合,默认是"None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。
    一般来说:弱分类器的参数不用调节
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles

# 生成2维正态分布,生成的数据按分位数分为两类,500个样本,2个样本特征,协方差系数为2
X1, y1 = make_gaussian_quantiles(cov=2.0,n_samples=500, n_features=2,n_classes=2, random_state=1)
#生成2维正态分布,生成的数据按分位数分为两类,400个样本,2个样本特征均值都为3,协方差系数为2
X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,n_samples=400, n_features=2, n_classes=2, random_state=1)
#讲两组数据合成一组数据
X = np.concatenate((X1, X2))
y = np.concatenate((y1, - y2 + 1))
#我们通过可视化看看我们的分类数据,它有两个特征,两个输出类别,用颜色区别。
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)

#建立模型
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=200, learning_rate=0.8)
bdt.fit(X, y)

#输出分数
print ("Score:", bdt.score(X,y))
"""
Score: 0.9133333333333333

也就是说拟合训练集数据的分数还不错。当然分数高并不一定好,因为可能过拟合。
现在我们将最大弱分离器个数从200增加到300。再来看看拟合分数。

"""
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=300, learning_rate=0.8)
bdt.fit(X, y)
print ("Score:", bdt.score(X,y))
"""
此时的输出为:

Score: 0.962222222222
    这印证了我们前面讲的,弱分离器个数越多,则拟合程度越好,当然也越容易过拟合。

    现在我们降低步长,将步长从上面的0.8减少到0.5,再来看看拟合分数。
"""
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
                         algorithm="SAMME",
                         n_estimators=300, learning_rate=0.5)
bdt.fit(X, y)
print ("Score:", bdt.score(X,y))
"""
此时的输出为:
Score: 0.894444444444
可见在同样的弱分类器的个数情况下,如果减少步长,拟合效果会下降。
"""

AdaBoost是模型为加法模型、损失函数为指数函数、学习算法为前向分步算法的二类分类学习方法,AdaBoost算法就是前向分步算法的一个特例
Adaboost是最早的提升树模型之一,根据Adaboost的发展,我们衍生出了gbdt提升树。
2、GBDT提升树
GBDT是提升树的一种,是一种基于残差的拟合模型。
一、引例
在这里插入图片描述
我们拟合了一个模型发现,每个数据都有残差,残差就是模型1未解决的问题,于是我们的模型就是基于模型1的残差对数据的一个拟合
在这里插入图片描述
继续 基于模型2的残差对数据进行拟合形成了模型3
在这里插入图片描述
通过不断的训练我们会使得残差越来越少。最终我们将训练出来的树的结果进行加法汇总就形成了一颗提升树
在这里插入图片描述
一、GBDT提升树
GBDT也是集成学习Boosting家族的成员,但是却和传统的Adaboost有很大的不同。回顾下Adaboost,我们是利用前一轮迭代弱学习器的误差率来更新训练集的权重,这样一轮轮的迭代下去。GBDT也是迭代,使用了前向分布算法,但是弱学习器限定了只能使用CART回归树模型,同时迭代思路和Adaboost也有所不同。
在GBDT的迭代中,假设我们前一轮迭代得到的强学习器是 f t 1 ( x ) f_{t−1}(x) , 损失函数是 L ( y , f t 1 ( x ) ) L(y,f_{t−1}(x)) , 我们本轮迭代的目标是找到一个CART回归树模型的弱学习器 h t ( x ) h_t(x) ,让本轮的损失函数L(y,f_t(x)=L(y,f_{t−1}(x)+h_t(x))最小。也就是说,本轮迭代找到决策树,要让样本的损失尽量变得更小。
GBDT的思想可以用一个通俗的例子解释,假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。
从上面的例子看这个思想还是蛮简单的,但是有个问题是这个损失的拟合不好度量,损失函数各种各样,怎么找到一种通用的拟合方法呢?
我们主要根据对函数的损失函数来进行判断的。
1、GBDT的回归算法
在这里插入图片描述
注意这里(a):
在这里插入图片描述
即用损失函数的负梯度来计算残差,并用残差来计算拟合值
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
则我们可以得到第一颗回归树,接着在第一颗回归树残差的基础上构建第二颗
注意:这里损失函数的负梯度就是残差。
在这里插入图片描述
其中求第二颗切分树时,我们是以残差为所在的序列为切分点的,并计算的是残差的误差平方和来进行切分点的寻找
其中1.93为上述残差的平方和
具体如下:

list1=[-0.68,-0.54,-0.33,0.16,0.56,0.81,-0.01,-0.21,0.09,0.14]
#计算残差的拟合情况
from numpy import mean
for i in range(1,10):
    left=list1[:i]
    right=list1[i:]
    left_mean=mean(left)
    right_mean=mean(right)
    left_ms=[(i-left_mean)**2 for i in left] 
    right_ms=[(i-right_mean)**2 for i in right]
    print(i+0.5,round(sum(left_ms)+sum(right_ms),2))
1.5 1.42
2.5 1.0
3.5 0.79
4.5 1.13
5.5 1.66
6.5 1.93
7.5 1.93
8.5 1.9
9.5 1.91

可以看出3.5最小
在这里插入图片描述
接着以同样的方法计算,下一个切分点
计算另一个切点:

x=[1,2,3,4,5,6,7,8,9,10]
y=[5.56,5.70,5.91,6.40,6.80,7.05,8.90,8.70,9.00,9.05]
def convert(num):
    if num<3.5:
        return 5.72
    if num>=3.5 and num<6.5:
        return 6.46
    if num>=6.5:
        return 9.13
y_pred=list(map(convert,x))
arr=[]
for i in range(len(y)):
    arr.append(round(y[i]-y_pred[i],4))
for i in range(1,10):
    left=arr[:i]
    right=arr[i:]
    left_mean=mean(left)
    right_mean=mean(right)
    left_ms=[(i-left_mean)**2 for i in left] 
    right_ms=[(i-right_mean)**2 for i in right]
    if i==6:
        print('x<=6.5:{:.4f}'.format(left_mean))
        print('x>6.5::{:.4f}'.format(right_mean))
    print(i+0.5,round(sum(left_ms)+sum(right_ms),4))
1.5 1.5537
2.5 1.5626
3.5 1.581
4.5 1.5801
5.5 1.5593
x<=6.5:0.1467
x>6.5:-0.0614
6.5 1.3991
7.5 1.4901
8.5 1.5716
9.5 1.5797

在这里插入图片描述
由于gbdt的基分类器为cart分类器,每次为二分类,所以其构建的模型如上面所示。下面来看看gbdt的具体做法

例2: 有两个自变量的梯度提升树
数据介绍:
如下表所示:一组数据,特征为年龄、体重,身高为标签值。共有5条数据,前四条为训练样本,最后一条为要预测的样本。
在这里插入图片描述
训练阶段:
参数设置:

学习率:learning_rate=0.1
迭代次数:n_trees=5
树的深度:max_depth=3
1.初始化弱学习器:
在这里插入图片描述
2.对迭代轮数m=1,2,…,M:
在这里插入图片描述
这里代表我们每次选用上一次生成树的残差作为下一颗树的标签值(因为是残差平方和,如果是别的损失函数,利用上面的求导公式进行计算)
在这里插入图片描述
在这里插入图片描述
以上划分点是的总平方损失最小为0.025有两个划分点:年龄21和体重60,所以随机选一个作为划分点,这里我们选 年龄21,现在我们的第一棵树长这个样子:
在这里插入图片描述
我们设置的参数中树的深度max_depth=3,现在树的深度只有2,需要再进行一次划分,这次划分要对左右两个节点分别进行划分:
对于左节点,只含有0,1两个样本,根据下表我们选择年龄7划分
在这里插入图片描述
对于右节点,只含有2,3两个样本,根据下表我们选择年龄30划分(也可以选体重70)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
即我每一次都用最新t-1棵树的预测值和真实值的残差作为切分点来进行选择最优的切分点。
这是什么意思呢
在这里插入图片描述
注意:跟上面一样对这个函数求导,求导以后其实算出来的就是各个叶子节点的均值(不同损失函数得出的值不一样)即γ=mean(叶子节点空间值的均值)
在这里插入图片描述
重复此步骤,直到m>5 结束,最后生成5棵树。
即第一棵树用真实值去进行切分,第二颗树用上一颗树的残差进行切分,第三棵树用第二颗树的残差进行切分,直到切分了5次。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、二元GBDT分类算法
在这里插入图片描述
其中最佳负梯度的拟合和回归树类似:
在这里插入图片描述

在这里插入图片描述
构建器参数:
①n_estimators: 也就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,又容易过拟合,一般选择一个适中的数值。默认是100。在实际调参的过程中,我们常常将n_estimators和下面介绍的参数learning_rate一起考虑。

②learning_rate: 即每个弱学习器的权重缩减系数ν,也称作步长,在原理篇的正则化章节我们也讲到了,加上了正则化项,我们的强学习器的迭代公式为fk(x)=fk−1(x)+νhk(x)。ν的取值范围为0<ν≤1。对于同样的训练集拟合效果,较小的ν意味着我们需要更多的弱学习器的迭代次数。通常我们用步长和迭代最大次数一起来决定算法的拟合效果。所以这两个参数n_estimators和learning_rate要一起调参。一般来说,可以从一个小一点的ν开始调参,默认是0.1。

③subsample: 即我们在原理篇的正则化章节讲到的子采样,取值为(0,1]。注意这里的子采样和随机森林不一样,随机森林使用的是放回抽样,而这里是不放回抽样。如果取值为1,则全部样本都使用,等于没有使用子采样。如果取值小于1,则只有一部分样本会去做GBDT的决策树拟合。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。推荐在[0.5, 0.8]之间,默认是1.0,即不使用子采样。

③init: 即我们的初始化的时候的弱学习器,拟合对应原理篇里面的f0(x),如果不输入,则用训练集样本来做样本集的初始化分类回归预测。否则用init参数提供的学习器做初始化分类回归预测。一般用在我们对数据有先验知识,或者之前做过一些拟合的时候,如果没有的话就不用管这个参数了。

④loss: 即我们GBDT算法中的损失函数。分类模型和回归模型的损失函数是不一样的。
分类的话采取最大似然损失函数,或者指数损失函数(交叉熵损失函数)
指数函数即我们前面所学的交叉熵损失函数:
在这里插入图片描述
对数似然函数:
则是对通过计算每个样本的概率,并利用最大似然估计计算出来的函数。

对于分类模型,有对数似然损失函数"deviance"和指数损失函数"exponential"两者输入选择。默认是对数似然损失函数"deviance"。在原理篇中对这些分类损失函数有详细的介绍。一般来说,推荐使用默认的"deviance"。
回归模型的损失函数
对于回归模型,有均方差"ls", 绝对损失"lad", Huber损失"huber"和分位数损失“quantile”。默认是均方差"ls"。一般来说,如果数据的噪音点不多,用默认的均方差"ls"比较好。如果是噪音点较多,则推荐用抗噪音的损失函数"huber"。而如果我们需要对训练集进行分段预测的时候,则采用“quantile”。

⑥alpha:这个参数只有GradientBoostingRegressor有,当我们使用Huber损失"huber"和分位数损失“quantile”时,需要指定分位数的值。默认是0.9,如果噪音点较多,可以适当降低这个分位数的值。
对于所有分类器的构建我们这里只修改参数:
n_estimate:弱分类器个数、learning_rate 学习率、subsample子采样的比例、loss损失函数

3、Xgboost
1、XGBOOST简介
XGBoost是Exterme Gradient Boosting(极限梯度提升)的缩写,它是基于决策树的集成机器学习算法,它以梯度提升(Gradient Boost)为框架。XGBoost是由由GBDT发展而来。但是相比于GBDT,xgboost有以下区别
目标函数:XGBoost的损失函数添加了正则化项,使用正则用以控制模型的复杂度,正则项里包含了树的叶子节点个数、每个叶子节点权重(叶结点的socre值)的平方和。
优化方法:GBDT在优化时只使用了一阶导数信息,XGBoost在优化时使用了一、二介导数信息。
缺失值处理:XBGoost对缺失值进行了处理,通过学习模型自动选择最优的缺失值默认切分方向。
防止过拟合: XGBoost除了增加了正则项来防止过拟合,还支持行列采样的方式来防止过拟合。
结果:它可以在最短时间内用更少的计算资源得到更好的结果。
2、项目知识
(1)如何使用多颗树进行预测
例1:
在这里插入图片描述
在这里插入图片描述
(2)目标函数的构建
在这里插入图片描述
f k ( x i ) f_k(x_i) 代表第k颗树对xi的预测值,因为是基于残差计算的,所以我们将k颗树的预测值进行汇总。最终会得到一个目标函数。这里的目标函数由两个部分来构成,其中一项是损失函数,另外一项是控制模型的复杂度。l(.,.)表示预测值与真实值之间的差异,可以灵活地做出选择。那么哪些指标和树的复杂度是相关的,主要包括树的深度和叶子节点的个数。
那让这棵树容易过拟合的,无非跟几个经典的特性相关,比如一个树的深度越深就越容易过拟合; 一个树越深也意味着它的叶节点越多,所以叶节点个数也可以作为衡量复杂度的一个很重要的要素。
其次还有叶子节点的预测值
在回归问题上,叶节点对应的预测值也是可以用来控制模型的复杂度的。比如这个预测值越大就说明模型越复杂,预测值越小说明模型越简单。
所以树的复杂度由三部分组成:
在这里插入图片描述
(3)叠加式训练
在这里插入图片描述
在这里插入图片描述
(2)将损失函数按泰勒级数展开
2.1、泰勒展开式的二阶形式为:
在这里插入图片描述
2.2 我们的损失函数为
在这里插入图片描述
在这里插入图片描述
(3)参数化 f k f_k ,
综上所述此时我们需要重新定义一下 f k f_k ,即怎样将 f k ( x i ) f_k(xi) 参数化
加入一棵树是这样的
在这里插入图片描述
将所有的叶子节点标记为w1,w2,w3
那么 f k ( x i ) f_k(xi) 代表用第k棵树预测xi的结果,那么 f k ( x i ) = w q ( x ) f_k(xi)=w_q(x) 代表x位于哪一个叶节点上的值。 q x i q_xi 代表位于叶子节点的位置
所以 q ( x 1 ) = 1 , q ( x 2 ) = 3 , q ( x 3 ) = 1 , q ( x 4 ) = 2 , q ( x 5 ) = 3 q(x1)=1,q(x2)=3,q(x3)=1,q(x4)=2,q(x5)=3
在这里插入图片描述
定义集合函数:
在这里插入图片描述
I j j I_j代表在第j个叶子节点下的样本数
(4)定义树的复杂度
在这里插入图片描述
同上,假如一颗决策树是这样的,那么我们定义树的复杂度为:
在这里插入图片描述
其中T为叶子节点的个数,叶子节点的个数越多证明模型越复杂,同时wi代表第i个叶子点的值,
那么这个叶子节点的值的平方和越大,模型也越复杂,因为分裂的叶子节点越多,得到的 w i w_i 的个数也越多,那么平方求和的值越大。r控制模型的叶子节点个数,λ控制叶子节点值的个数
在这里插入图片描述
在这里插入图片描述
此时我们xgboost损失函数救计算好了。

再次总结,上面的一大堆推导最后得到的结果就是:xgb引入了树的正则化的概念,在原始的损失函数的基础上加入了正则项(类似与逻辑回归的损失函数加入了正则项)并且通过将带正则项的损失函数进行二阶泰勒展开推导出了叶子节点的新的计算方式。但每一轮要拟合的值还是通过负梯度计算得到的。
(5)如何通过树的分裂来找到最优的树结构
假设一棵树长这样
在这里插入图片描述
在这里插入图片描述
所以我们选择特征进行分割时不再是选用cart决策树的gini系数了,而是选择上述的分割函数。即
在这里插入图片描述
每次选择一个特征,分别计算特征各个分裂点的分割函数,利用分割函数最大选择分裂点。不断重复缔造一颗决策树
(5)xgboost主要算法流程
在这里插入图片描述
在这里插入图片描述
由于xgboot的优化函数利用到了左右子树的一阶和二阶导数,所以可以计算出所有特征与所有分裂的左右一阶与二阶导数,方便后期进行计算,以来提升迭代的效率
(6)xgboost的参数调整
(1) booster决定了XGBoost使用的弱学习器类型,可以是默认的gbtree, 也就是CART决策树,还可以是线性弱学习器gblinear以及DART。一般来说,我们使用gbtree就可以了,不需要调参。

(2) n_estimators则是非常重要的要调的参数,它关系到我们XGBoost模型的复杂度,因为它代表了我们决策树弱学习器的个数。这个参数对应sklearn GBDT的n_estimators。n_estimators太小,容易欠拟合,n_estimators太大,模型会过于复杂,一般需要调参选择一个适中的数值。

(3) objective代表了我们要解决的问题是分类还是回归,或其他问题,以及对应的损失函数。具体可以取的值很多,一般我们只关心在分类和回归的时候使用的参数。

在回归问题objective一般使用reg:squarederror ,即MSE均方误差。二分类问题一般使用binary:logistic, 多分类问题一般使用multi:softmax。
弱学习器参数
(1) max_depth: 控制树结构的深度,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,需要限制这个最大深度,具体的取值一般要网格搜索调参。这个参数对应sklearn GBDT的max_depth。
(3)gamma: XGBoost的决策树分裂所带来的损失减小阈值。也就是叶子节点个数前面的控制值
在这里插入图片描述
可以直到γ越大树越复杂
(4)λ,同样是控制树的复杂程度的系数
(5) subsample: 子采样参数,这个也是不放回抽样,和sklearn GBDT的subsample作用一样。选择小于1的比例可以减少方差,即防止过拟合,但是会增加样本拟合的偏差,因此取值不能太低。初期可以取值1,如果发现过拟合后可以网格搜索调参找一个相对小一些的值。

猜你喜欢

转载自blog.csdn.net/weixin_41611045/article/details/102414794